TypeScript - 环境声明 (Ambients)
TypeScript - 声明文件 (.d.ts)
Section titled “TypeScript - 声明文件 (.d.ts)”TypeScript 的强大之处来自于其静态类型系统。然而,许多 JavaScript 生态系统中的现有库是在没有 TypeScript 类型的情况下编写的。声明文件(使用 .d.ts 扩展名)弥合了这一差距。
声明文件为 TypeScript 编译器描述现有 JavaScript 代码的形状(类型、函数签名、类、变量)。它告诉 TypeScript 期望什么类型,从而在使用 JavaScript 库时,在 TypeScript 项目中实现类型检查、自动补全和重构支持。
声明文件只包含类型信息;它们没有实现代码,也不会被编译成 JavaScript 输出。它们纯粹是为了开发人员和编译器在开发过程中的便利。
获取声明文件
Section titled “获取声明文件”有几种方法可以获取 JavaScript 库的声明文件:
- 随库打包: 许多用 TypeScript 编写或积极维护的现代 JavaScript 库现在直接在其 npm 包中包含自己的
.d.ts文件。安装这类库时,TypeScript 会自动找到并使用这些类型。 - DefinitelyTyped (
@types): 这是一个由社区驱动的巨大仓库,包含数千个流行 JavaScript 库的声明文件。你可以从 npm 的@types作用域下安装某个库(例如,lodash、react、node)的类型。例如:npm install --save-dev @types/lodash。TypeScript 编译器会自动在node_modules/@types中查找类型。 - 自己编写: 如果库或 DefinitelyTyped 中没有可用的类型,你可以自己编写一个
.d.ts文件来描述你使用的库的部分。对于内部 JavaScript 代码或不太常见的库,这通常是必需的。
使用声明文件:@types 示例
Section titled “使用声明文件:@types 示例”让我们以流行的 lodash 库为例。首先,安装库及其类型:
npm install lodashnpm install --save-dev @types/lodash现在,你可以在你的 TypeScript 代码中导入和使用 lodash 函数,并获得完整的类型安全和自动补全:
import _ from 'lodash';
const numbers = [1, 5, 8, 10, 1, 5];
const uniqueNumbers = _.uniq(numbers);console.log(uniqueNumbers); // 输出: [ 1, 5, 8, 10 ]
const message = "hello world";const capitalizedMessage = _.capitalize(message);console.log(capitalizedMessage); // 输出: Hello world
// 尝试错误地使用函数 - TypeScript 会捕获错误:// const result = _.uniq("not an array"); // 错误:类型 'string' 的参数不能赋值给类型 'List<any> | null | undefined' 的参数。因为我们安装了 @types/lodash,TypeScript 理解 _.uniq、_.capitalize 和其他 lodash 函数的签名。
编写基本的声明文件 (declare)
Section titled “编写基本的声明文件 (declare)”当你需要描述没有现成类型的 JavaScript 代码时,可以在 .d.ts 文件中(有时对于简单情况也可以直接在 .ts 文件中)使用 declare 关键字。
想象一个简单的 JavaScript 库 my-js-lib.js:
// my-js-lib.js (假设此文件存在)function greetLib(name) { return `Hello from lib, ${name}!`;}
const LIBRARY_VERSION = '1.0.0';你可以创建一个对应的 my-js-lib.d.ts 文件:
// my-js-lib.d.ts
// 声明 JavaScript 文件中存在的函数declare function greetLib(name: string): string;
// 声明存在的常量变量declare const LIBRARY_VERSION: string;
// 你也可能声明模块、类、接口等declare module 'some-other-module' { export function processData(data: any): void;}现在,在你的 TypeScript 代码中,假设 JavaScript 文件已通过某种方式加载(例如,通过 <script> 标签或打包工具),你可以使用这些声明的元素进行类型检查:
/// <reference path="my-js-lib.d.ts" />// (如果未使用模块系统或 tsconfig includes,可能需要三斜线引用)
const greeting = greetLib("TypeScript 用户");console.log(greeting);console.log(`库版本: ${LIBRARY_VERSION}`);
// const wrongGreeting = greetLib(123); // 错误:类型 'number' 的参数不能赋值给类型 'string' 的参数。declare 关键字向 TypeScript 表明实现存在于其他地方,它应该信任所提供的类型签名。
- 目的: 为现有 JavaScript 代码提供类型信息。
- 扩展名:
.d.ts - 内容: 仅包含类型声明(接口、类型、函数签名、
declare var/let/const/function/class/module...),不包含实现代码。 - 运行时: 对生成的 JavaScript 代码没有影响。
- 获取方式: 随库打包、DefinitelyTyped (
@types) 或手动编写。 declare关键字: 在.d.ts文件中使用,用于描述环境(ambient,现有)代码。
理解和利用声明文件对于有效地将 TypeScript 集成到依赖于 JavaScript 库的项目中至关重要,它可以确保整个代码库的类型安全。