我可以在打字稿中测试另一个泛型类型的泛型吗?

时间:2021-07-08 02:24:09

标签: typescript

假设我有一个泛型类型,例如 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)

1 个答案:

答案 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

这个函数的返回类型是我们可以提取那些泛型参数的地方。

第一个说如果 TA<any, any, any> 的子类型,那么推断这些槽中每个泛型参数的类型。然后,您可以在条件类型的 ? 之后使用这些类型。

如果 T 不扩展 A<any, any, any> 则它跳到最后一行并变成 never。虽然在这种情况下,这不可能发生,因为约束可以分配给这种类型。但这是使用 infer SomeType 所需的语法。

现在我们可以对其中一种类型进行测试。在这种情况下,我们测试它是否是带有 stringX extends string。如果是字符串,则类型变为true,否则变为false

Playground


实现这个功能是另一回事,我纯粹是在回答这个问题。