编程前端开发者 / 全栈开发者

TypeScript中的模块系统是如何工作的?它与JavaScript模块有什么区别?TypeScript的类型声明和导出有什么特点?

用 Hintsage AI 助手通过面试

答案

TypeScript支持JavaScript的两种主要模块系统 — CommonJS和ES模块,允许使用关键字importexport来组织代码。TypeScript的一个区别是拥有可以像值一样导出和导入的类型声明。

例如,可以导出一个接口:

// types.ts export interface User { id: number; name: string; } // index.ts import { User } from './types'; const u: User = { id: 1, name: 'Alice' };

还支持export typeexport interfaceimport type,这允许仅导入类型而不将代码拉入最终的bundle中,从而优化构建:

import type { User } from './types';

一个重要的特点是:在TypeScript中只能导出不会出现在最终JavaScript中的类型。

设问

import { SomeType } from './file'import type { SomeType } from './file'有什么区别?

错误答案:它们是一样的。

正确答案import { SomeType } ...可能导致整个模块被导入并包含在生成的JavaScript中,即使这只是一个类型。import type { SomeType } ...确保仅在编译阶段导入类型,没有副作用或代码输出。

真实错误示例


故事

在一个大型项目中,团队通过常规导入import { SomeType } ...从一个有副作用的模块(例如,在require/import时运行代码)中导入类型。结果是生产构建中引入了额外的依赖和副作用,导致了错误并增加了包的大小。


故事

开发者决定通过全局变量描述一个全局类型,而不是通过类型声明,并不小心导出了同名的类型和值。这导致在多个文件中名称冲突,并在更新TypeScript后构建失败。


故事

团队无法区分export/import type的特点,错误地将类型与数据一起导出。结果是tree-shaking工具无法排除死代码,增加了bundle的大小。