TypeScript 声明文件(.d.ts)详解
.d.ts 声明文件为无类型的 JavaScript 提供类型契约。本文讲解编写声明文件、TS 的发现机制与 @types 生态。
声明文件(.d.ts)只含类型不含实现——为 JS 库描述类型契约:declare module 'lib' { export function fn(x: string): number }。TS 按 node_modules/@types、types 字段、include 路径自动发现它们。
解决什么问题
引入无类型的 JS 库,TS 报"找不到模块的类型声明"——声明文件补全这个缺口:不碰库源码,纯类型层描述。
编写声明文件
// types/mylib.d.ts
declare module 'my-lib' {
export function init(options: { debug?: boolean }): void;
export function track(event: string, data?: Record<string, unknown>): void;
export const version: string;
}
// 全局变量型库
declare const gtag: (command: string, ...args: unknown[]) => void;
declare 系列关键字(module/function/const/class/namespace)描述"外面世界有什么"。
发现机制
TS 按顺序查找类型:
- 包自身的 types/typings 字段;
- @types/包名(DefinitelyTyped 生态——
npm i -D @types/lodash); - tsconfig include/typeRoots 内的 .d.ts。
复杂场景
- 为存量 JS 文件补类型:同名 .d.ts 或 JSDoc 注释 + checkJs;
- 模块增强(declaration merging):给已有模块追加声明(扩展 Express Request 类型);
- 打包发布库:tsc 自动生成 .d.ts(declaration: true)——库作者的义务。
常见问题(FAQ)
Q:.d.ts 会被编译吗?
不会产出代码——纯类型信息,编译后消失。写实现代码会报错。
Q:@types 版本和库版本对不上?
@types 独立维护有滞后——版本选择就近即可,缺失的新 API 用模块增强临时补充。
Q:公开资料未说明 和 any 在声明文件里怎么选?
宁可 公开资料未说明 不可 any——any 会从声明文件传染整个项目的类型安全。
参考文档
本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。