我正在编写一个简单的泛型函数,如下所示:
function x<T>(a: T[], b: T) {
return ''
}
x(['hello', 'world'], 'world')
我希望用户在第一个参数中输入一个字符串数组,例如:
['red', 'yellow', 'green']
我希望第二个参数的类型为string,并且它必须是前一个参数中提供的值之一,因此代码编辑器应该显示以下选项的自动完成:
- 红色
- 黄色
- 绿色
如果用户试图编写这些以外的代码,代码编辑器(或者说编译器)应该显示错误。
实现这一目标的最佳途径是什么?
3条答案
按热度按时间wecizke31#
可以通过创建扩展第一个泛型参数的第二个泛型参数来强制推理的方向。
注意,
T
需要一个约束,如T extends string
。没有它,T
被推断为string
,而不是任何字符串类型。添加string
约束似乎迫使编译器认为它可能是string
的子类型。见Playground
您也可以关闭该约束,并传递数组
as const
,如下所示:见Playground
或者,如果您使用的是Typescript 5.0,则const使用
const
泛型类型,以告诉typescript默认情况下推断为const。见Playground
所有这些选项看起来都很适合自动完成:
vktxenjb2#
这很可能是不可能的。您的函数在运行时可能会接收不同的输入,因此不可能知道代码在编译时(TypeScript检查您的类型)将如何运行。例如,如果我传递了一个随机生成的数组,那么编译器如何知道一个值是否会在随机生成的数组中?
与输入不同,看起来您希望执行输入验证,即在运行时检查输入。在您的情况下,这真的很容易:
h5qlskok3#
如果用户愿意将
as const
附加到a
值,则以下代码对我有效:这样,我的VSCode编辑器就为
b
的自动完成提供了a
的值(没有readonly
和as const
,T
通常被推断为string
)。但是我发现我仍然可以为
b
输入其他string
值而不会出错,所以编译器似乎没有强制执行这一点,相反,它默默地扩展了T
联合类型以容纳为b
给定的任何值。我使用的是VSCode、Angular Language Service和TypeScript 4.9。