假设我有一个泛型类型,例如 type A<X, Y, Z> = {}
。我可以创建一个测试函数来检测输入值的具体类型扩展这个 type A
吗?
type A<X, Y, Z> = {}
const a : A<number, string, boolean>
function test<T extends A>(toTest:T) {
// Can I test type X, Y, Z of input value here?
}
test(a)
答案 0 :(得分:1)
有点难说,但我想你想要这样的东西?
type A<X, Y, Z> = {}
declare function test<T extends A<unknown, unknown, unknown>>(toTest: T):
T extends A<infer X, infer Y, infer Z>
? X extends string
? true
: false
: false
declare const a: A<number, string, boolean>
test(a) // false, X is not a string
declare const b: A<string, string, boolean>
test(b) // true, X is a string
让我们分解一下。
首先是通用约束:
function test<T extends A<unknown, unknown, unknown>>(toTest: T)
A 类型的泛型参数必须有值,但您不必承诺这些值是什么。此处的 unknown
仅用作占位符,可让您传入任何内容。
接下来是这个嵌套的条件类型:
T extends A<infer X, infer Y, infer Z>
? X extends string
? true
: false
: never
这个函数的返回类型是我们可以提取那些泛型参数的地方。
第一个说如果 T
是 A<any, any, any>
的子类型,那么推断这些槽中每个泛型参数的类型。然后,您可以在条件类型的 ?
之后使用这些类型。
如果 T
不扩展 A<any, any, any>
则它跳到最后一行并变成 never
。虽然在这种情况下,这不可能发生,因为约束可以分配给这种类型。但这是使用 infer SomeType
所需的语法。
现在我们可以对其中一种类型进行测试。在这种情况下,我们测试它是否是带有 string
的 X extends string
。如果是字符串,则类型变为true
,否则变为false
。
实现这个功能是另一回事,我纯粹是在回答这个问题。