深入typescript: 简易 dependent type 实现

1,214 阅读1分钟

最近经常碰到有同事需要一些实现的复杂的函数类型,即根据函数前序的函数的实参类型确定后续参数的类型。

我们以 zhuanlan.zhihu.com/p/95828198 的例子为例

interface FooParams {
  type: "foo"
  value: string
}

interface BarParams {
  type: "bar"
  value: number
}

type Params = FooParams | BarParams

function test<TParams extends Params>(
  type: TParams["type"],
  value: TParams["value"]
): void {}

这里的目的是,第二个参数 value 的类型由第一个参数的实参类型确定,这实际上就是 Dependent type , @vilicvane 介绍了一种通过多泛型参数约束的实现, _虽然 Typescript 目前不直接支持 Dependent_type,但是借助于其函数重载和 conditional type 的支持,我们可以实现一个乞丐版 dependent_type_ depdentype playground

本例的核心思路就是:

  • 通过 distributive conditional types 和 infer 将 Type Variable 进行拆分映射为不同的函数类型的 union
  • 通过 union2intersection 将 函数 union 转换为函数 intersection
  • 函数 inersection 可以当做函数重载使用
  • 函数重载时只对外暴露 overload signature 并不对外暴露 implementation signature