本文探讨 TypeScript 如何在 d.ts
文件中使用 import
语句.
在类型定义文件 typings/basic.d.ts
中,定义一个组件需要的数据类型
interface BasicState {
departmentTree: TreeSelectOption[];
}
但这个 TreeSelectOption
类型是组件库提供的, 按照常规想法, 我们应该这样处理:
import TreeSelectOption from 'naive-ui'
interface BasicState {
departmentTree: TreeSelectOption[];
}
但问题是,这样加入 import
语句之后, basic.d.ts
中所定义的类型就全部失效了.
经过调研, 发现原理如下:
TypeScript 有两类模块声明, 局部模块和全局模块. 局部模块就如同常规的 ESModules, 我们需要手动 import/export. 而全局模块则会自动导入当前模块,无须显示声明.
d.ts
文件就属于全局模块, 但有个前提: 不能使用 import
语句. 一旦使用 import
, d.ts
文件就被当做局部模块, 需要手动导入才能使用, 这就是前面类型失效的原因. (我猜测这是防止出现循环引用的问题.)
那么, 如果的确需要在全局模块中引入第三方类型, 该怎么办呢? 可以采用动态导入的方法.以开头的案例来说, 可以采用如下方式:
interface BasicState {
departmentTree: import('naive-ui').TreeSelectOption[];
}
不在外层使用独立的 import
语句, 而是使用内联 import
语句, 就能够避免 d.ts
文件变成局部模块.