TypeScript类型工具里的lodash,200+类型体操一站搞定

ts-toolbelt 在 GitHub 上获得了 7,141 个 Star:

正文顶部截图

README区域截图

ts-toolbelt 包含超过 200 个类型工具函数。它在 TypeScript 类型体操领域的角色,类似于 lodash 在 JavaScript 运行时工具函数领域的地位。lodash 操作运行时的值,ts-toolbelt 操作编译时的类型。

所有 TypeScript 项目都会用到类型操作。标准库自带的 Partial、Required、Pick、Omit 等内置类型,在日常开发中能覆盖一部分场景。一旦遇到嵌套的对象映射、多层条件分支、联合类型的交并补运算,就需要另想办法。过去遇到这些情况,开发者只能手写映射类型、条件类型和递归类型。写出正确的类型体操往往需要反复调试。ts-toolbelt 把这些操作封装成了可复用的 API,开发者不需要从零开始写类型逻辑。


按模块组织,覆盖 TypeScript 核心概念

ts-toolbelt 按照 TypeScript 的类型体系划分子模块:

  • Any:处理任意类型的工具,如 Await(提取 Promise 内的类型)、Cast(类型断言)、Compute(展开交叉类型)、Equals(判断类型相等)、Try(安全执行类型操作)
  • Object:对象类型操作集合,如 Merge(合并对象)、Diff(找出差异键)、Optional(将指定键变为可选)、Required(将指定键变为必填)、Filter(按条件筛选键)、Path(按路径获取值类型)
  • List:元组类型操作集合,如 Append/Prepend(在首尾追加元素)、Concat(拼接元组)、Reverse(反转顺序)、Drop/Take(截取子集)、Zip(按位置合并两个元组)
  • Function:函数类型操作,如 Curry(柯里化)、Compose/Pipe(函数组合)、Parameters(提取参数类型)、Return(提取返回值类型)、NoInfer(阻止类型推断)
  • String:字符串字面量类型操作,如 Join(拼接)、Split(分割)、Replace(替换)、Length(获取长度)、At(获取指定位置字符)
  • Number:数字字面量类型的数学运算,如 Add、Sub、Greater、Range(生成数字范围)、Negate(取反)
  • Union:联合类型的运算,如 Diff(差集)、Filter(筛选)、IntersectOf(转交叉类型)、NonNullable(去除 null 和 undefined)
  • Boolean:布尔类型的逻辑运算,And、Or、Not、Xor

项目给每个工具类型都配有文档页面,说明用法和参数,同时附带可运行的代码示例。


安装

npm install typescript@^4.1.0 --save-dev
npm install ts-toolbelt --save

建议在 tsconfig.json 中开启:

{
  "compilerOptions": {
    "strictNullChecks": true,
    "strict": true,
    "lib": ["es2015"]
  }
}

strictNullChecks 是部分工具的前置依赖,建议一并开启。


使用示例

导入方式有三种:

按模块名显式导入:

import {Object, List, Union} from "ts-toolbelt"

短名导入,每个模块用一个字母:

import {O, L, U} from "ts-toolbelt"

单入口导入:

import tb from "ts-toolbelt"

对象类型操作:

import {Object} from "ts-toolbelt"

// 合并两个对象类型
type user = Object.Merge<{name: string}, {age?: number}>
// {name: string, age?: number}

// 将指定键变为可选
type partialUser = Object.Optional<{id: number, name: string}, "name">
// {id: number, name?: string}

// 递归提取路径
type paths = Object.Paths<{user: {name: string; age: number}}>
// "user" | "user.name" | "user.age"

数字类型运算:

import {Number} from "ts-toolbelt"

type sum = Number.Add<1, 30>   // 31
type diff = Number.Sub<10, 3>  // 7
type cmp = Number.Greater<5, 3>  // 1 (true)

元组操作:

import {List} from "ts-toolbelt"

type rev = List.Reverse<[1, 2, 3]>      // [3, 2, 1]
type hd = List.Head<["a", "b", "c"]>    // "a"
type tl = List.Tail<["a", "b", "c"]>    // ["b", "c"]

内置类型测试框架

ts-toolbelt 的 Test 模块可以在编译阶段验证类型结果的正确性,不需要实际运行代码:

import {Number, Test} from "ts-toolbelt"

const {checks, check} = Test

checks([
    check<Number.Add<1, 30>, 31, Test.Pass>(),
    check<Number.Add<5, -3>, 2,  Test.Pass>(),
])

把这段代码放入不会被实际执行的 .ts 文件中,TypeScript 编译时会自动完成类型校验。如果类型不匹配,编译器会直接报错。


版本策略

ts-toolbelt 的主版本号跟随 TypeScript 大版本升级。当前 v9.x.x 对应 TypeScript 4.1.x 及以上版本。TypeScript 发生破坏性变更时,ts-toolbelt 会同步发布新的主版本,其余情况沿用语义化版本号。


文档与社区

项目提供在线文档,每个工具类型都有对应页面。过往每个大版本的文档也做了存档。使用过程中遇到问题可以到 Discussions 提问,社区欢迎新手和资深开发者参与讨论。项目还开放了 Community API,允许社区贡献和发布不属于标准 API 范畴的类型工具。

文档与社区

项目提供在线文档,每个工具类型都有对应页面。过往每个大版本的文档也做了存档。使用过程中遇到问题可以到 Discussions 提问,社区欢迎新手和资深开发者参与讨论。项目还开放了 Community API,允许社区贡献和发布不属于标准 API 范畴的类型工具。

更多推荐