typescript 从返回类型推断为窄字符串文本类型

6tqwzwtp  于 2022-12-30  发布在  TypeScript
关注(0)|答案(3)|浏览(164)
const createFruit = <T extends string[]>(fruits: T): typeof fruits[0] => fruits[0]

const fruit = createFruit(['apple', 'orange']) // fruit is of type `string`

我希望fruit的类型被推断为字符串字面量apple,难道没有办法做到吗?

ve7v8dk2

ve7v8dk21#

fruits参数使用variadic tuple语法将提示编译器推断文本类型。

const createFruit = <T extends string[]>(
  fruits: [...T]
): typeof fruits[0] => fruits[0]

const fruit = createFruit(['apple', 'orange'])
//    ^? fruit: "apple"

Playground

np8igboo

np8igboo2#

为了获得更强的类型化以提供所需的行为,只需将参数输入为不可变数组,然后使用constAssert输入作为参数传递的值:

const createFruit = <T extends readonly string[]>(fruits: T): typeof fruits[0] => fruits[0]

const fruit = createFruit(['apple', 'orange'] as const) // fruit is of type `apple`

TypeScriptPlayground

j7dteeu8

j7dteeu83#

在TS 5.0中,您将能够使用const modifier on type parameters,如下所示:

const createFruit = <const T extends readonly string[]>(fruits: T): T[0] => fruits[0]

const fruit = createFruit(['apple', 'orange'])

目前可能的解决方案如下:

const createFruit = <N extends string, T extends N[] | []>(fruits: T): T[0] => fruits[0]

const fruit = createFruit(['apple', 'orange'])

其中声明了另一个类型参数N,以将推断范围从字符串缩小到实际的字符串类型文字,然后将T的上限设置为T[] | [],其中| []告诉TS推断元组类型而不是数组类型。
在这两种情况下,返回类型都可以是T[0]

相关问题