TypeScript 僅僅導入聲明語法

一種「預期」的行爲

在 TypeScript 中,若是導入的模塊沒有用於任何表達式,TypeScript 將會刪除該模塊導入。git

import { xxx } from './module';

let a: xxx = /* something */;
複製代碼

編譯後:github

var a = /* ssomething */;
複製代碼

若是你須要強制導入該模塊,你可使用 import 'module' 語法:babel

import './module';
複製代碼

這有時候很是糟糕,試想若是一個模塊若是含有反作用,可是並無用到任何表達式中:ide

// source-component.ts
export class SourceComponent extends HTMLElement {
  // 其餘代碼
}
customElements.define('source-component', SourceComponent);
複製代碼
import {SourceComponent} from './source-component.js';

const example = document.createElement('source-component') as SourceComponent;
複製代碼

在正常編譯時,TypeScript 將會在編碼者絕不知情的狀況下捨棄 source-component.ts 文件。待到提測階段,你可能纔會發現問題所在,查找、抱怨以後,會加上 import './source-component.js' 這樣一行代碼,來讓編譯器強制導入該模塊。ui

其次,使用 isolatedModules 編譯選項時,如下代碼。會出現編譯錯誤的問題:編碼

export { AType } from './module' // Cannot re-export a type when the '--isolatedModules' flag is provided
複製代碼

在筆者查閱相關資料後,瞭解到 isolatedModules 編譯選項,實際上是「確保個人程序代碼能夠被不進行任何類型檢查的編譯器正確地編譯」(如 babel)。spa

當在 babel 運行如下程序時,也會拋出錯誤:code

// Export 'MyType' is not defined
export { MyType } from './module';
複製代碼

爲了正常編譯經過,你須要改爲以下方式:component

import { AType as BType } from './module';
export type AType = BType;

// 或者
export type AType = import('./module').AType
複製代碼

僅導入/導出類型

在即將到來的 3.8 版本中,有一個提案 import type,旨在解決上述中的問題。cdn

它提供瞭如下語法:

import type T from './mod';
import type { A, B } from './mod';
import type * as Types from './mod';

export type { T };
export type { T } from './mod';
複製代碼

import type 用來告訴 TypeScript 編譯器,僅僅是導入/導出類型:

// a.ts
export default calss A{}

// b.ts
import type A from './a';

new A(); // error,

function f(obj: A) {} // ok
複製代碼

所以在默認狀況下,TypeScript 將不會再刪除任何 import 導入語句:

import { T } from './module';
import x: T;
複製代碼

編譯後:

import "./module";
let x;
複製代碼

而且對於在使用 isolatedModules 編譯選項時,export { AType } from './module' 的問題,只需改寫成 export type { T } from './mod'; 便可解決。

ps: TypeScript 3.8 大概在 2020 年 2 月發佈。

參考

若是你對 TypeScript 感興趣,能夠經過京東、噹噹等渠道購買《深刻理解 TypeScript》。

或者你也能夠關注下面公衆號,獲取更多內容

相關文章
相關標籤/搜索