教程

TypeScript 类型体操的边界

2 分钟1 条评论

类型系统是 TypeScript 最好的礼物,也可能是最坏的诱惑。什么时候该用复杂的类型推导,什么时候该停下来,值得认真讨论。

类型体操真正值钱的场景#

抽公共库的时候,类型体操回报最高。一个经典的例子——把对象类型的值域取出来:

type Values<T> = T[keyof T]

const STATUS = {
  idle: 'idle',
  loading: 'loading',
  done: 'done',
} as const

type Status = Values<typeof STATUS> // 'idle' | 'loading' | 'done'

这类推导的好处是单一事实来源:运行时对象和类型永远同步,没有第二处需要维护。

什么时候应该刹车#

遇到这几种信号,就该退回简单方案:

  • 类型参数出现三层以上的条件嵌套,报错信息已经没人读得懂;
  • 为了类型完备,运行时被塞进了只服务于类型的代码;
  • 团队里超过一半的人无法修改这段类型。

类型是给人看的,不是给编译器写的诗。

务实的替代方案#

很多"高难推导"其实有平替:

  1. 代码生成:schema 生成类型,简单粗暴、永远准确;
  2. 声明合并 + 显式断言:把不确定性圈在一个有注释的小范围里;
  3. 测试兜底:用 expectTypeOf 之类的工具把类型预期写成测试,复杂度被文档化。

我的判断标准#

一句话:库代码可以聪明,业务代码必须无趣。业务代码的读者是半年后的自己和刚入职的同事,无趣是一种美德。

评论 1

登录后即可参与讨论。

  • R
    Raymond

    "库代码可以聪明,业务代码必须无趣",这句话值得贴在工位上。