前言

最近用 TypeScript 写 npm 包,各种模块、命名空间、全局定义等等扰得我睡不着觉。

我便苦心研究,总结了几个比较冷门的,国内貌似基本上找不到资料的导入导出用法,顺便在其中又插入一些不那么冷门的用法,于是本篇文章来了。

因为一开始也没想做成大全,可能之后还会继续更新吧。

目录

导入模块

导入模块中的东西相信大家都不陌生。唯一需要注意的便是默认导出与“星号”导出的区别。

import * as Mod from './mod';
// 类似于
const Mod = require('./mod');
import ModDef from './mod';
// 类似于
const { default: ModDef } = require('./mod');
import ModDef, { a, b } from './mod';

// 类似于
const {
default: ModDef,
a, b
} = require('./mod');

在模块中导出

在模块中导出东西相信大家也不陌生,不过这里还是详细讲解一下。

在模块中导出东西有很多种方法。导出总共可分为 4 类:

命名导出

命名导出有两种方法,一种是声明着导出

export namespace A { }
export function b() { }
export class C { }
export const d = 123;
export let { e } = { e: 'hh' };

一种是声明后导出

namespace A { }
function b() { }
class C { }
const d = 123;
let { e } = { e: 'hh' }; export { A, b, C, d, e };

声明后导出比声明着导出更灵活,能合并,也能重命名

namespace A { }
export { A }; function b() { }
export { b as c }; class C { }
export { C as B }; const d = 123;
let { e } = { e: 'hh' };
export { d, e };

命名导出编译成 Common JS 后类似这样

exports.xxx = xxx;

需要注意的是其他人无法修改任何你导出的东西。即使是使用 let 声明也一样

/* mod.ts */
export let a = 123; /* others.ts */
import { a } from './mod';
a = 321; // 报错:ts(2632)

不过对于上面的代码,你可以随便修改所导出的 a 。因为其他人每次读取 a 时都会重新从你的导出对象上访问一次 a 属性,不用担心其他人无法接收到你的修改。具体可以查看编译后的 JS 文件

/* others.ts */
import { a } from './mod';
const b = a + 123;
console.log(a); /* others.js */
var mod_1 = require("./mod");
var b = mod_1.a + 123;
console.log(mod_1.a);

默认导出

默认导出可以理解为一种特殊的命名导出。

默认导出的名字是 default 。但是你不能搞个名字叫 default 的变量然后导出,你必须得用 export default 或者在导出时重命名

export let default = 123; // 报错:ts(1389)

export default 123; // 正确

export let a = 123;
export { a as default }; // 正确

星号导出

星号导出可以导出其他模块里的东西。一般有两种用法。

第一种是全导出到自己里头,就像

export * from './xxx'

具体效果是 xxx 中导出的东西,也可以通过你访问到。

/* xxx.ts */
export let a = { hh: 'hh' }; /* mod.ts */
export * from './xxx.ts'; /* others.ts */
import { a } from './xxx';
import { a } from './mod';
console.log(a === a); // true

第二种是挂到自己模块下面,就像

export * as xxx from './xxx';
// 等价于
import * as xxx from './xxx';
export { xxx };

导出分配

导出分配就是把 Common JS 的导出搬到了 TS 中。写法也差不多

export = 'hh';
// 相当于
module.export = 'hh';

导出分配也可以指定默认导出,只需要有 default 属性就可以

/* mod.ts */
export = { default: 123 }; /* others.ts */
import mod from './mod';
console.log(mod); // 123

需要注意的是采用了导出分配后便不能再使用其他导出方法。

导入命名空间

虽然现在命名空间相较于模块并不是特别常用,但它还是有比较完整的导入导出功能的。

导入命名空间中的东西很简单,像这样

import xxx = Space.xxx;

不论你是在模块中导入全局命名空间,还是在命名空间中导入其他命名空间,都是适用的。

import Err = globalThis.Error;
throw Err('hh'); namespace A {
import Process = NodeJS.Process;
let proce: Process;
}

较为可惜的是命名空间貌似没有星号导入,也不支持解构导入。

在命名空间中导出

在一般 TS 中,命名空间只有两种方法导出。

第一种方法是声明着导出,类似于模块

namespace A {
export const a = 123;
}

第二种方法是导入着导出,可以用来导出其他命名空间的东西

namespace A {
export import Err = globalThis.Error;
}

而对于不一般的 TS ——也就是类型声明中,命名空间还可以采用像模块一样的导出对象

declare namespace A {
const a = 123;
const b = 'hh';
export { a, b };
}

使用全局定义

全局定义一般有三种:

  1. 内置在 TS 中的全局定义。比如 setTimeoutError 等。

    对于这种全局定义,直接拿来用就可以了。

  2. 位于环境模块中的全局定义。比如 NodeJS.Process 等。

    包括位于 node_modules/@types 文件夹中的自动引入的环境模块,都可以通过三斜杠注释来引入。

    你可以通过 path 直接指定文件路径

    /// <reference path="./types.d.ts" />
  3. 位于模块中的全局定义。

    这种全局定义只需要引入一下模块,表示你已经运行此模块,即可

    import '@babel/core';

    或者你也可以通过三斜杠注释,通过 types 指定模块

    /// <reference types="@babel/core" />

    需要注意的是,不论你采用 import 还是三斜杠注释,甚至只是在类型中使用了一个 typeof import('xxx') ,只要你在一个 TS 文件中引入了这个模块所定义的全局类型,那这个类型就会永远存在下去,污染你的 globalThis

    唯一在不污染全局域的情况下运行模块的方法是使用 import() 函数动态引入,但这样子你也拿不到你需要的类型。

进行全局定义

进行全局定义一般有三种方法。

第一种是直接写环境模块。不带任何 importexport 一般就会让编译器把这当成一个环境模块。所以,如果你需要防止一个 TS 文件变成环境模块导致类型泄露的话,你可以加一个安全无公害的 export { };

第二种是在模块中定义,只需要把类型定义写到 declare global 里头就行

declare global {
const a = 123;
let b: {};
}
export { };

第三种是通过合并 globalThis 命名空间来定义,好处是可以使用命名空间的“导入着导出”方法,将模块或者其他命名空间的局部变量变成全局变量

import _Mod from './mod';

declare global {
namespace globalThis {
const a = 123;
export import Mod = _Mod;
}
}

TS 导入导出那些事的更多相关文章

  1. Excel导入导出的业务进化场景及组件化的设计方案(上)

    1:前言 看过我文章的网友们都知道,通常前言都是我用来打酱油扯点闲情的. 自从写了上面一篇文章之后,领导就找我谈话了,怕我有什么想不开. 所以上一篇的(下)篇,目前先不出来了,哪天我异地二次回忆的时候 ...

  2. Java利用POI导入导出Excel中的数据

         首先谈一下今天发生的一件开心的事,本着一颗android的心我被分配到了PB组,身在曹营心在汉啊!好吧,今天要记录和分享的是Java利用POI导入导出Excel中的数据.下面POI包的下载地 ...

  3. (转)Linux下Oracle启动、建立表空间、用户、授权、数据库导入导出

    Linux系列 启动1.启动数据库实例,分为两步:第一步,启动监听:第二步,启动数据库实例. 1.1进入到sqlplus启动实例 [oracle@redhat ~]$ su - oracle      ...

  4. Mego(04) - NET简单实现EXCEL导入导出

    前言 相信做过信息系统的朋友都会遇到EXCEL导入导出的相关开发,做过不少EXCEL导入导出后总结起来大致有如下几种方式实现: ADO.NET的OldDb或ODBC连接EXCEL使用DataTable ...

  5. 3. orcle导入导出dmp文件并更改表空间

    0.数据泵导入导出: expdp  test/test@10.0.0.11/orcl schemas=test dumpfile=test.dmp directory=DPDATA  logfile= ...

  6. C#中缓存的使用 ajax请求基于restFul的WebApi(post、get、delete、put) 让 .NET 更方便的导入导出 Excel .net core api +swagger(一个简单的入门demo 使用codefirst+mysql) C# 位运算详解 c# 交错数组 c# 数组协变 C# 添加Excel表单控件(Form Controls) C#串口通信程序

    C#中缓存的使用   缓存的概念及优缺点在这里就不多做介绍,主要介绍一下使用的方法. 1.在ASP.NET中页面缓存的使用方法简单,只需要在aspx页的顶部加上一句声明即可:  <%@ Outp ...

  7. 【DB2】文件导入导出常见命令总结 EXPORT IMPORT LOAD

    参考文献地址:https://blog.csdn.net/reaper1022/article/details/18601973 Db2 的数据迁移,最常用的就是导入导出功能,而导入导出的命令貌似简单 ...

  8. CRUD全栈式编程架构之导入导出的设计

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  9. easypoi 一行代码搞定excel导入导出

    开发中经常会遇到excel的处理,导入导出解析等等,java中比较流行的用poi,但是每次都要写大段工具类来搞定这事儿,此处推荐一个别人造好的轮子[easypoi],下面介绍下“轮子”的使用. pom ...

  10. consul备份还原导入导出

    工作中要保证生产环境部署的consul的集群能够安全稳定地对外提供服务,即使出现系统故障也能快速恢复,这里将讲述部分的备份还原操作及KV的导入导出操作. 备份与还原 需要备份的主要有两类数据:cons ...

随机推荐

  1. ansible使用报错not possible

    一.问题描述: 执行ansible webservers -m ping报错如下(hosts文件指定ssh_user,ssh_pass) 二.解决方案 vim /etc/ansible/ansible ...

  2. pt-query-digest 工具使用分析

    pt-query-digest是用于分析mysql慢查询的一个工具,它可以分析binlog.General log.slowlog,也可以通过SHOW PROCESSLIST或者通过tcpdump抓取 ...

  3. Linux配置

    JDK安装 一.登录虚拟机进入终端切换到root用户,输入:su 接着输入密码 再输入:cd - 回到root用户 二.接着在终端进入对应文件新建一个装jdk包的文件夹,输入:mkdir +目录名称 ...

  4. iOS Unity 项目解析

    本文旨在记录Unity 导出的iOS 项目笔记,另带接入SDK的终极方案,顺带对比Android 项目 1蓝色的目录 Data 这个就是项目的数据,每个项目不一样也就是这个目录不一样,是不是可以把这个 ...

  5. 点击事件触发count自增

    1.vue3合成API :(即为什么要用setup() :为了数据更加关联) vue3 引入setup()合成API语法,它可以将某数据关联的内容整合到一个部分,即使setup里的内容越来越多也会围绕 ...

  6. 中国移动光猫(吉比特h2-3S)超级用户名与密码

    超级用户名 CMCCAdmin 密码 aDm8H%MdA

  7. PHP递归的简单理解

    递归简单来说就是自己调用自己 比如说 A向B问路 但是B不知道 于是乎B问C 但是C不知道 于是乎问D D知道 D把怎么走告诉C C在把怎么走告诉B B再把怎么走告诉A A虽然是最先问的 但是是最后一 ...

  8. How to enable CIFS in kernel 4.9

    kernel config 要打开这几项

  9. 在DeepIn系统中使用eclipse创建maven的Web项目

    1. 安装好jdk和eclipse以后,启动eclipse 2. 创建maven项目,选择Maven Project 3. 在创建项目过程中,创建简单Maven项目,不使用archetype创建(会联 ...

  10. app 好用的手机端开发调试工具插件 vconsole vue3

    效果:可以在手机上看控制台的内容 $ npm install vconsole 在main.js里引入 // 添加移动端log查看调试器 import Vconsole from 'vconsole' ...