如何限制泛型参数可分配给字符串?

How can I constrain generic parameter to be assignable to string?

我有一个带有通用参数的函数 T。我希望这个通用参数是不同常量字符串的总和类型,如 "alpha"|"beta",或者是具有字符串值的枚举,如 enum ExampleEnum { Alpha = "ALPHA", Beta = "BETA" }。无论哪种方式,在运行时所有值都将是字符串,我应该能够在任何使用字符串的地方使用它们。

示例函数如下:

function chooseRandom<T>(inputs: T[], callback: (chosen: T) => void) {
  const t = inputs[4]; // die roll, guaranteed to be random
  acceptsOnlyString(t);
  callback(t);
}

function acceptsOnlyString(input: string) {
  console.log(input);
}

当然,有了这个,我在调用 acceptsOnlyString:

时出错

Type 'T' is not assignable to type 'string'

我在这个例子中包含了回调函数来解释为什么我不能只使用 stringchooseRandom 函数的用户会想要指定一个只接受 T 而不是任何可能的字符串。

我如何向打字稿解释 T 应该限制为可分配给字符串的类型?

您可以使用 extends 关键字限制泛型允许的类型:

function chooseRandom<T extends string>(inputs: T[], callback: (chosen: T) => void) {
  const t = inputs[4]; // die roll, guaranteed to be random
  acceptsOnlyString(t);
  callback(t);
}

有了这个限制,typescript 知道将 t 传递给 acceptsOnlyString

是安全的

Playground link