DefinitelyTyped

DefinitelyTyped 是 TypeScript 社区维护的类型声明仓库,为大量 JavaScript 库提供类型声明。通过 @types/xxx 包可以方便地安装类型声明。

什么是 DefinitelyTyped

DefinitelyTyped 是 GitHub 上的开源项目,包含数千个库的类型声明文件。这些类型声明由社区维护,确保 JavaScript 库可以在 TypeScript 项目中使用。

GitHub 仓库地址:https://github.com/DefinitelyTyped/DefinitelyTyped

安装类型声明

使用 npm 安装类型声明包。

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

类型声明包以 @types/ 为前缀,作为开发依赖安装。

常用类型声明

常用的类型声明包:

npm install @types/node --save-dev
npm install @types/react --save-dev
npm install @types/react-dom --save-dev
npm install @types/express --save-dev
npm install @types/jest --save-dev
npm install @types/jquery --save-dev
npm install @types/axios --save-dev

类型声明结构

类型声明包的结构:

node_modules/@types/lodash/
  index.d.ts
  common/
  fp/

index.d.ts 是主类型声明文件,包含库的类型定义。

使用类型声明

安装类型声明后,直接导入库即可获得类型支持。

import _ from "lodash"

const numbers = [1, 2, 3, 4, 5]
const doubled = _.map(numbers, (n) => n * 2)
const sum = _.sum(numbers)

console.log(doubled)
console.log(sum)

IDE 会提供智能提示和类型检查。

版本管理

类型声明包的版本应该与库的版本匹配。

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

版本号格式:主版本.次版本.补丁

贡献类型声明

可以向 DefinitelyTyped 贡献类型声明:

  1. Fork DefinitelyTyped 仓库
  2. types/ 目录下创建库的目录
  3. 编写类型声明文件
  4. 提交 Pull Request

类型声明文件模板:

declare module "my-library" {
  export interface Config {
    apiKey: string
    debug?: boolean
  }

  export function init(config: Config): void
  export function doSomething(value: string): number
}

类型声明测试

DefinitelyTyped 要求类型声明包含测试文件。

import { init, doSomething } from "my-library"

init({ apiKey: "test", debug: true })

const result = doSomething("hello")
console.log(result)

测试文件验证类型声明的正确性。

类型声明质量

高质量的类型声明应该:

  • 准确描述库的 API
  • 包含完整的文档注释
  • 支持泛型和高级类型
  • 包含测试用例
export interface User {
  id: number
  name: string
  email: string
}

export function fetchUser(id: number): Promise<User>
export function updateUser(user: Partial<User>): Promise<User>
export function deleteUser(id: number): Promise<void>

类型声明配置

tsconfig.json 中配置类型声明。

{
  "compilerOptions": {
    "typeRoots": ["./types", "./node_modules/@types"],
    "types": ["node", "lodash", "jest"]
  }
}

types 选项限制只加载指定的类型声明。

实际应用

在项目中使用多个类型声明包。

import express, { Request, Response } from "express"
import { Pool } from "pg"
import bcrypt from "bcrypt"
import jwt from "jsonwebtoken"

const app = express()
const pool = new Pool({
  host: "localhost",
  port: 5432,
  database: "mydb"
})

app.post("/login", async (req: Request, res: Response) => {
  const { email, password } = req.body

  const result = await pool.query("SELECT * FROM users WHERE email = $1", [
    email
  ])
  const user = result.rows[0]

  if (!user) {
    return res.status(401).json({ error: "用户不存在" })
  }

  const valid = await bcrypt.compare(password, user.password)
  if (!valid) {
    return res.status(401).json({ error: "密码错误" })
  }

  const token = jwt.sign({ userId: user.id }, "secret", { expiresIn: "1h" })
  res.json({ token })
})

app.listen(3000, () => {
  console.log("服务器启动在端口 3000")
})

小结

DefinitelyTyped 是社区维护的类型声明仓库,提供 @types/xxx 包。安装类型声明包后获得类型检查和智能提示。可以向 DefinitelyTyped 贡献类型声明。高质量的类型声明应该准确描述库的 API,包含文档注释和测试用例。合理使用类型声明可以提高 TypeScript 项目的开发效率。