TypeScript具有查找类型和开关大小写的类型推理



我有以下TypeScript代码:

type Test = {
a: string;
b: boolean;
c: number;
}
const instance: Test = {
a: 'a',
b: true,
c: 2,
}
function getValue<T extends keyof Test>(val: T): Test[T] {
return instance[val];
}
function setValue<T extends keyof Test>(key: T, value: Test[T]): void {
instance[key] = value;
onChangeValue(key, value);
}
function onChangeValue<T extends keyof Test>(key: T, value: Test[T]): void {
switch (key) {
case 'a':
let a: string = value; // why TS won't infer that value must be type Test['a'] ie. string? Is there any way to fix it?
break;
case 'b':
let b: boolean = value;
break;
case 'c':
let c: number = value;
break
}
}
let d: number = getValue('c'); // works fine
setValue('a', 'fsdfdsf'); // works fine

所以基本上,我有一些方法,它们接受一个参数,即对象(类型(中的键,第二个参数是设置对象中键值的值。我在这里使用基于传递的键的值的查找类型。对于基于键返回值并基于键设置值的方法的使用,它运行良好。然而,我有第三个函数onChangeValue,其中我想根据键参数的类型来识别值参数的类型。为什么它在这里不起作用?为什么编译器不能正确推断值参数的类型?有没有任何方法可以在没有显式类型转换的情况下修复它并使其工作?

正如@jcalz在他们的评论中指出的,onChangeValue的类型并不意味着value的类型是特定的类型。

例如,当您像这样声明一个常量k时,它的类型将变为'a' | 'b'

const k: 'a' | 'b' = true ? 'a' : 'b' as const

然后,当您使用k调用onChangeValue时,onChangeValue将被实例化为function onChangeValue<'a' | 'b'>(key: 'a' | 'b', value: string | boolean): void

onChangeValue(k, true);

正如您所看到的,即使key'a'value也可以是boolean。这就是为什么编译器不缩小switchvalue的类型。

最新更新