前言

最近用 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 中的全局定义。比如 setTimeout 、 Error 等。

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

  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() 函数动态引入,但这样子你也拿不到你需要的类型。

进行全局定义

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

第一种是直接写环境模块。不带任何 import 和 export 一般就会让编译器把这当成一个环境模块。所以,如果你需要防止一个 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. lgb文档学习

    1.L1和l2损失是什么意思? 相较于MSE,MAE有个优点,那就是MAE对离群值不那么敏感,可以更好地拟合线性,因为MAE计算的是误差y−f(x)的绝对值,对于任意大小的差值,其惩罚都是固定的. 2 ...

  2. mkcert 生成本地SSL证书 IIS 安装

    下载mkcert https://github.com/FiloSottile/mkcert/releases/latest 管理员身份 cmd 命令目录下 mkcert-v1.4.4-windows ...

  3. 基础实验之access/trunk/valn/vlanif/静态路由

     实验要求 1,PC1,PC2,PC3,PC4分别属于VLAN10,20,30,40 2,PC1,PC2,PC3,PC4互通 步骤1:PC1,2,3,4分别配置IP,并在SW6,SW7分别配置网关,并 ...

  4. 循环神经网络(Recurrent Neural Networks)(第一部分)

    参考 https://www.cnblogs.com/royhoo/p/Recurrent-Neural-Networks-1.html

  5. RabbitMQ安装失败 地址提示错误

    最后设置为: D:\RabbitMQ\rabbitmq_server-3.7.10-rc.3\sbin>set ERLANG_HOME=D:\Erlang\erl10.2

  6. pod进阶

    一.Lifecycle 官网:https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/ 通过前面的分享,关于pod是什么相信看 ...

  7. Web服务器2

    Web服务器2 基于华为鲲鹏云服务器CentOS中(或Ubuntu),使用Linux Socket实现: Web服务器的客户端服务器,提交程序运行截图 实现GET即可,请求,响应要符合HTTP协议规范 ...

  8. 红米k40稳定版本刷开发版开启DC调光记录

    刷个开发版还要申请资格.要么去淘宝买资格的账号,要么用其他方法: 包21.4.15,直接有有防闪烁功能下载地址:https://bigota.d.miui.com/21.4.15/miui_ALIOT ...

  9. 后端006_登录之后返回Token

    现在开始我们就可以写登录相关的东西了.首先登录相关的流程是这样的,前端输入用户和密码传给后端,后端判断用户名和密码是否正确,若正确,则生成JWT令牌,若不正确,则需要让前端重新输入,前端如果拿到了JW ...

  10. P2962 [USACO09NOV]Lights G(Meet In The Middle)

    [USACO09NOV]Lights G 题目描述 给出一张n个点n条边的无向图,每个点的初始状态都为0. 你可以操作任意一个点,操作结束后该点以及所有与该点相邻的点的状态都会改变,由0变成1或由1变 ...