声明文件

声明文件是 TypeScript 为 JavaScript 代码提供类型信息的方式。通过声明文件,可以为现有的 JavaScript 库添加类型支持,获得类型检查和智能提示。

什么是声明文件

声明文件以 .d.ts 为扩展名,只包含类型声明,不包含实现代码。声明文件描述了 JavaScript 代码的类型结构。

declare function greet(name: string): string

declare const PI: number

declare class User {
  constructor(name: string)
  getName(): string
}

declare 关键字告诉编译器这些声明存在于其他地方。

声明文件的作用

声明文件的主要作用:

  • 为 JavaScript 库提供类型信息
  • 获得类型检查和智能提示
  • 提高代码的可维护性
  • 减少运行时错误

声明文件的来源

声明文件有几种来源:

  1. 内置类型声明:TypeScript 自带的类型声明
  2. 库自带声明:库作者提供的声明文件
  3. DefinitelyTyped:社区维护的类型声明
  4. 自定义声明:自己编写的声明文件

内置类型声明

TypeScript 自带 JavaScript 内置对象的类型声明。

const arr: Array<number> = [1, 2, 3]
const map: Map<string, number> = new Map()
const promise: Promise<string> = Promise.resolve("hello")

console.log(arr.length)
console.log(map.size)
console.log(promise.then)

内置类型包括 ArrayMapSetPromiseDate 等。

库自带声明

很多库自带类型声明文件。

{
  "name": "my-library",
  "version": "1.0.0",
  "main": "index.js",
  "types": "index.d.ts"
}

types 字段指定类型声明文件的路径。

DefinitelyTyped

DefinitelyTyped 是社区维护的类型声明仓库,提供 @types/xxx 包。

npm install lodash
npm install @types/lodash --save-dev

安装后自动获得类型支持。

import _ from "lodash"

const result = _.chunk([1, 2, 3, 4], 2)
console.log(result)

自定义声明文件

当库没有类型声明时,可以自己编写。

declare module "my-library" {
  export function greet(name: string): string
  export const version: string
}

使用自定义声明文件。

import { greet, version } from "my-library"

console.log(greet("张三"))
console.log(version)

全局声明

声明文件可以定义全局变量。

declare const API_URL: string
declare function log(message: string): void

console.log(API_URL)
log("Hello")

全局声明在所有文件中可用。

声明文件查找

TypeScript 按以下顺序查找声明文件:

  1. node_modules/@types/
  2. tsconfig.json 中的 typeRoots
  3. tsconfig.json 中的 types
  4. 模块的 package.json 中的 types 字段

实际应用

声明文件常用于为 JavaScript SDK 提供类型支持。

declare namespace MySDK {
  interface Config {
    apiKey: string
    baseUrl?: string
    timeout?: number
  }

  interface User {
    id: string
    name: string
    email: string
  }

  function init(config: Config): void
  function getUser(id: string): Promise<User>
}

declare const MySDK: {
  init: (config: MySDK.Config) => void
  getUser: (id: string) => Promise<MySDK.User>
}

使用 SDK 时获得类型提示。

MySDK.init({
  apiKey: "your-api-key",
  baseUrl: "https://api.example.com",
  timeout: 5000
})

async function main() {
  const user = await MySDK.getUser("123")
  console.log(user.name)
}

main()

小结

声明文件以 .d.ts 为扩展名,为 JavaScript 代码提供类型信息。声明文件可以来自内置类型、库自带、DefinitelyTyped 或自定义。declare 关键字用于声明外部定义的类型。声明文件让 JavaScript 库获得 TypeScript 的类型支持,提高代码的可维护性。