第7章:模块与命名空间
外部库的声明文件(*.d.ts)
1. 什么是声明文件?
声明文件(.d.ts)是 TypeScript 中用于描述 JavaScript 库或模块类型的特殊文件。它们不包含具体实现,仅提供类型信息,使得 TypeScript 编译器能够对非 TypeScript 编写的代码进行类型检查。
2. 声明文件的作用
- 类型安全:为纯 JavaScript 库添加类型支持
- 智能提示:在 IDE 中提供代码补全和文档提示
- 兼容性:允许 TypeScript 项目无缝使用现有的 JavaScript 生态
3. 声明文件的来源
(1) DefinitelyTyped (@types)
大多数流行库都有社区维护的类型定义:
npm install --save-dev @types/lodash
(2) 库内置类型
现代库通常自带类型声明(如 package.json 中的 types 字段指定)
(3) 自定义声明
当库没有现成类型时,可以手动创建:
// globals.d.ts
declare module 'untyped-lib' {
export function doSomething(config: any): void;
}
4. 声明文件的编写规范
基本结构示例:
// my-library.d.ts
declare namespace MyLibrary {
interface Config {
timeout: number;
retries?: number;
}
function initialize(config: Config): void;
function getVersion(): string;
}
declare module 'my-library' {
export = MyLibrary;
}
常见声明语法:
declare var/let/const:声明全局变量declare function:声明全局函数declare class:声明全局类declare namespace:声明命名空间declare module:声明模块interface和type:声明类型
5. 三斜线指令
用于声明文件间的依赖关系:
/// <reference types="node" /> // 依赖 @types/node
/// <reference path="./local.d.ts" /> // 依赖本地文件
6. 最佳实践
- 优先使用 @types:检查是否存在官方或社区维护的类型定义
- 最小化声明:只为实际使用的部分编写类型
- 类型合并:利用声明合并扩展现有类型
- 版本匹配:确保声明文件版本与库版本兼容
7. 常见问题解决
问题1:无法找到模块声明
// 解决方案1:创建声明文件
declare module 'module-without-types';
// 解决方案2:禁用检查(不推荐)
// @ts-ignore
import lib from 'untyped-lib';
问题2:类型定义冲突
- 检查是否有多个 @types 版本
- 使用类型断言临时解决特定情况
8. 高级技巧
- 使用
typeof import获取模块类型:
import type * as _moment from 'moment';
declare const moment: typeof _moment;
- 条件类型与声明文件结合:
declare module 'config' {
export function get<T extends keyof Config>(key: T): Config[T];
interface Config {
env: 'dev' | 'prod';
port: number;
}
}
注意:TypeScript 4.1+ 支持
typesVersions字段,允许包作者为不同 TypeScript 版本提供不同的类型定义。
