Typescript Tips: 动态重载实现廉价版dependent type

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

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

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
编辑于 2019-12-07