TypeScript 類型推斷與查找類型及 switch case
我有以下 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,我希望在其中根據鍵參數的類型來識別值參數的類型。為什麼在這裡不起作用?為什麼編譯器無法正確推斷值參數的類型?有沒有辦法解決這個問題,使它在不顯式類型轉換的情況下也能正常運作?
答案#1
正如 @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。這就是為什麼編譯器不會在 switch 中縮小 value 的類型。
