咱们先来看一个具体的例子:javascript
在 Node 项目里,使用 CommonJS 规范引入一个模块:html
const koa = require('koa')
复制代码
改写为 TypeScript(1.5+ 版本)时,一般有两种方式:java
使用 ES6 模块导入方式:git
// allowSyntheticDefaultImports: false
import * as koa from 'koa'
复制代码
使用 TypeScript 模块导入语法:typescript
import koa = require('koa')
复制代码
二者大部分是等价的,但 ES6 规范对 import * as
建立出的模块对象有一点限制。 根据该规范,该模块对象不可被调用,也不可被实例化,它只具备属性。app
所以,若是你想调用该对象,或者使用 new 方法,在 allowSyntheticDefaultImports: false
的配置下,应该使用例子中的第二种方式。koa
在以前的版本,TypeScript 对 CommonJs/AMD/UMD 模块的处理方式与 ES6 模块相同,这会致使一些问题:ui
如前文所提到的,当导入一个 CommonJs/AMD/UMD 模块时,TypeScript 视 import * as koa from 'koa'
与 const koa = require('koa')
等价,但使用 import * as
建立的模块对象实际上不可被调用以及被实例化。this
相似的,当导入一个 CommonJs/AMD/UMD 模块时,TypeScript 视 import foo from 'foo'
与 const koa = require('koa').default
等价,但在大部分 CommonJs/AMD/UMD 模块里,它们并无默认导出。google
在 2.7 的版本里,TypeScript 提供了一个新选项 --esModuleInterop
,旨在解决上述问题, 当使用该选项,且模块为 CommonJs/AMD/UMD 时,它会导入一个可调用或是可实例化的模块,同时它规定该模块必须做为默认导入:
import koa from 'koa'
const app = new koa()
复制代码
在以非相对路径导入一个模块时,你可能会看到 Could not find a declaration file for module 'someModule'
的错误, 此时你能够安装对应模块的声明文件或者写一个包含 declare module 'someModule'
的声明文件。
实际上,当咱们导入一个模块时:
import koa from 'koa'
// import koa = require('koa')
复制代码
它所作的事情只有两个:
当你加载此模块,但并无使用,或仅看成类型来使用时,编译后,此模块将会被移除。
当不使用时;
import koa from 'koa'
复制代码
编译后:
复制代码
仅当作类型使用时:
import koa from 'koa'
let k: koa
复制代码
编译后:
var k
复制代码
作为值使用时,编译后,此模块将会被保留:
import koa from 'koa'
const app = new koa()
复制代码
编译后(假设使用 commonjs):
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var koa_1 = __importDefault(require("koa"));
var k = new koa_1.default();
复制代码
注:__importDefault
为使用 --esModuleInterop
选项时产生的方法。