使用TypeScript类型/接口进行动态类型推断

时间:2020-08-20 23:25:05

标签: typescript

我正在尝试编写一个具有返回类型UnpackedValuesOnly的函数,该函数可以动态确定“打包”值K的类型,而用户不必明确定义{{1 }}是。

这里距离我能走的很近

K

上面有一些主要缺点:

  1. 允许有限数量的//pretend that this is a useful class for some reason class PackedValue<T> { value: T constructor(value: T) { this.value = value } } //This is my best attempt at dynamically unpacking the type of a PackedValue type UnpackedValuesOnly<T, K = any, K2 = any, K3 = any, K4 = any, K5 = any> = { [P in keyof T]: T[P] extends PackedValue<K> ? K : T[P] extends PackedValue<K2> ? K2 : T[P] extends PackedValue<K3> ? K3 : T[P] extends PackedValue<K4> ? K4 : T[P] extends PackedValue<K5> ? K5 : UnpackedValuesOnly<T[P], K, K2, K3, K4, K5> } const unpackObj = <T, K = any, K2 = any, K3 = any, K4 = any, K5 = any>(toUnpack: T): UnpackedValuesOnly<T, K, K2, K3, K4, K5> => { //implementation unimportant, assume that non packed values are preserved, packed values are unpacked return {} as any as UnpackedValuesOnly<T, K, K2, K3, K4, K5> } const foo = { a: 'hello', b: new PackedValue([ 1, 3 ]), c: new PackedValue('asdf') } const bar = unpackObj<typeof foo, number[]>(foo) //type of string bar.a //type of number[] bar.b //type of any bar.c 类型,在这种情况下为5
  2. 用户在调用PackedValue时必须明确定义所有使用的PackValue类型,否则这些类型将显示为unpackObj类型,并且会丢失所有编译器检查

是否有一种编写any的方法,以便下面的示例代码将允许编译器/ lint通过隐式确定UnpackedValuesOnly的类型来报告正确的类型?

PackedValue

1 个答案:

答案 0 :(得分:2)

是的,有一种使用infer关键字的方法:

type UnpackedValueOnly<T> = {
    [key in keyof T]: T[key] extends PackedValue<infer U> ? U : T[key]
}

选中此TS sandbox并将鼠标悬停在Test上,以查看变量foo的初始类型为

{
  a: string
  b: PackedValue<number[]>
  c: PackedValue<string>
}

打开包装后

{
  a: string
  b: number[]
  c: string
}