typescript - setter 中的 Proxy 屬性從未有過類型(附 MRE)
使用 TypeScript 4.5.4(目前最新版本),以下代碼(見下方或在 TypeScript playground 中)對於版本 1、2、3、4 會拋出錯誤 Type 'any' is not assignable to type 'never'.(2322),但對於版本 5 和 6 則不報錯。如果我們移除其中一個 num 屬性或 str 屬性,所有錯誤都會消失。
這個設計有解釋嗎?
const myObj = {
num: -1,
arr: [1, 2, 3],
str: '',
};
const proxy = new Proxy(myObj, {
set(target, prop: keyof typeof myObj, value) {
/* none of these works */
// Ver. 1
if (prop in target) target[prop] = value;
// Ver. 2
target[prop] = value;
// Ver. 3
target[prop as keyof typeof myObj] = value;
// Ver. 4
switch (prop) {
case 'num':
case 'str':
target[prop] = value;
break;
}
/* while these works */
// Ver. 5
switch (prop) {
case 'num':
target[prop] = value;
break;
case 'str':
target[prop] = value;
break;
}
// Ver. 6
switch (prop) {
case 'num':
target[prop] = value;
break;
default:
target[prop] = value;
break;
}
return true;
},
});
console.log('proxy : ', proxy);
答案#1
摘要
在 TS 中,寫作會產生類型交集。
詳細
這是來自官方倉庫 microsoft/TypeScript#47295 的回答副本,這是一個「按預期工作」的功能。
在你大多數的設置中,
prop的類型並沒有從"num" | "str" | "arr"中縮小;因為你是 寫入 到target[prop]而不是從中讀取,這會產生一個所有可能類型的交集(而不是聯集)。如果沒有重疊,這個交集就會崩潰為never,因為沒有一個可能的值適用於所有類型。
這個答案是為了結束這個問題而創建的。