咱們先來看一個具體的例子: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
選項時產生的方法。