我正在尝试编写一个具有返回类型UnpackedValuesOnly
的函数,该函数可以动态确定“打包”值K
的类型,而用户不必明确定义{{1 }}是。
这里距离我能走的很近
K
上面有一些主要缺点:
//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 PackedValue
时必须明确定义所有使用的PackValue
类型,否则这些类型将显示为unpackObj
类型,并且会丢失所有编译器检查是否有一种编写any
的方法,以便下面的示例代码将允许编译器/ lint通过隐式确定UnpackedValuesOnly
的类型来报告正确的类型?
PackedValue
答案 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
}