其思想是我可以提供2个参数,而第一个参数将提供一个字符串列表,对于第二个参数,我只想允许第一个参数中提供的值成为对象的允许键。
这就是我所尝试的。
declare function test<T extends readonly string[]>(a: T, b?: Record<typeof a[number], string>): unknown
test(['a', 'b'], {
a: 'someValue',
b: 'someOtherValue',
c: 'thisShouldNotWork' // no error shown, as typescript only infers string[]
})
我知道你可以从一个元组创建一个UnionType,所以我的想法是这应该是可能的。对于Union to Tuple,它看起来像这样,并产生预期的行为:
const arg1 = ['a', 'b'] as const
type Arg1 = typeof arg1
declare function test<T>(a: T, b?: Record<T[number], string>): unknown
test<Arg1>(arg1, {
a: 'someValue',
b: 'someOtherValue',
c: 'thisShouldNotWork'
})
我想要的是一个有点像我最初的方法的解决方案,其中我不需要为所有需要的参数提取UnionType。
任何帮助都是感激的!
2条答案
按热度按时间oalqel3c1#
这里的主要问题是,您希望编译器为作为参数传递给
test
的数组元素推断"someValue" | "someOtherValue"
之类的字符串类型,但目前它推断的是string
。编译器使用各种启发式来确定它是否应该推断文字类型。TypeScript 5.0很可能包含这样的功能:向generic类型参数声明添加
const
修饰符,以请求与const
Assert中相同类型的文字首选项。这在microsoft/TypeScript#51865中实现。释放后,您可以获得所需的行为,如下所示:现在最简单的方法是重构函数,使其仅在数组的元素类型中泛型,而不是在整个数组中泛型。当您将泛型类型参数约束为
string
时,它将倾向于推断类型参数的文本类型,如microsoft/TypeScript#10676中所述:即使在TS5.0发布之后,我也可能会建议您这样做,除非您有某种原因关心输入数组的特定形状。
Playground代码链接
guz6ccqo2#
如果将文本类型赋给约束为文本生成类型(如
string
)的类型参数,则Typescript将推断文本类型最简单的解决方案是为数组中的项使用类型参数,并将其约束为string:
Playground链接