This website requires JavaScript.

TypeScript 仅仅导入声明语法

2019.12.28 14:58 字数 2346 喜欢 6 评论 0

一种「预期」的行为

在 TypeScript 中,如果导入的模块没有用于任何表达式,TypeScript 将会删除该模块导入。

import { xxx } from './module';

let a: xxx = /* something */;

编译后:

var a = /* ssomething */;

如果你需要强制导入该模块,你可以使用 import 'module' 语法:

import './module';

这有时候非常糟糕,试想如果一个模块如果含有副作用,但是并没有用到任何表达式中:

// 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' 这样一行代码,来让编译器强制导入该模块。

其次,使用 isolatedModules 编译选项时,以下代码。会出现编译错误的问题:

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

在笔者查阅相关 资料 后,了解到 isolatedModules 编译选项,其实是「确保我的程序代码可以被不进行任何类型检查的编译器正确地编译」(如 babel)。

当在 babel 运行以下程序时,也会抛出错误:

// Export 'MyType' is not defined
export { MyType } from './module';

为了正常编译通过,你需要改成如下方式:

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

// 或者
export type AType = import('./module').AType

仅导入/导出类型

在即将到来的 3.8 版本中,有一个提案 import type ,旨在解决上述中的问题。

它提供了以下语法:

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 月 发布。

参考

Contact

微信公众号

微信

相关推荐

暂无推荐文章