![](/img/trans.png)
[英]Why does TypeScript infer the 'never' type when reducing an Array with concat?
[英]Why does Typescript infer 'never' instead of intersection type?
給出以下示例:
interface Data {
name: string;
value: number;
}
const data :Data = {
name: 'name',
value: 1,
}
const updateValue = (key: keyof Data, value: string | number): void => {
data[key] = value;
};
Typescript顯示以下錯誤:
Type 'string | number' is not assignable to type 'string & number'.
Type 'string' is not assignable to type 'string & number'.
Type 'string' is not assignable to type 'number'.
這是清楚易懂的。 但是,如果我將一個聯合類型添加到接口,如下所示:
type MultiType = 'x' | 'y';
interface Data {
name: string;
value: number;
multiType: MultiType | null;
}
const data :Data = {
name: 'name',
value: 1,
multiType: null,
}
const updateValue = (key: keyof Data, value: string | number): void => {
data[key] = value;
};
我收到以下錯誤:
Type 'string | number' is not assignable to type 'never'.
Type 'string' is not assignable to type 'never'.
如果我使用交集類型string & number & MultiType
但是它也接受never
,那么Typescript接受它。
這似乎與我不一致。 這可能是個錯誤嗎?
string & number
等於never
, string & number & (MultiType | null)
。 沒有值既是string
又是number
,因此沒有值滿足string & number
或string & number & AnythingElse
。
現在,后者明確地減少到never
因為它包含這些等價到never
類型的聯合,這樣做真的很難看。 具體來說,編譯器將交叉點分布在聯合上,因此
string & number & ('x' | 'y' | null)
變
(string & number & 'x') | (string & number & 'y') | (string & number & null)
這種類型對人們來說並不是特別有啟發性,因此編譯器會檢查每個聯合組成部分是否等同於never
,並將類型減少為
never | never | never
這只是
never
如你所見。
那么為什么string & number
本身不會立即減少到never
? 最初的想法是,它可以幫助人們了解代碼中的錯誤來自哪里,因為string is not assignable to number
更具啟發性, string is not assignable to never
。
不幸的是,雖然string & number
相當於 never
分配給它的值,但在TS3.5及更低版本中,編譯器並不總是將它們視為相同,這是令人困惑的。
因此看起來,從TS3.6開始, 像string & number
這樣的空交叉將never
明確地減少到 。 一旦TS3.6發布,你的上述代碼在兩種情況下的行為都相同,你將獲得string | number is not assignable to never
string | number is not assignable to never
錯誤。
好的,希望有所幫助; 祝好運!
兩件事情 :
TypeScript不接受string | number
合乎邏輯的 string | number
作為value
參數的類型,因為以下所有內容:
string | number
string | number
不能賦值給string
因為如果key
是'name'
則number
不能賦值給string
string | number
string | number
不能分配給number
因為如果key
是'value'
,則string
不能分配給number
(在第一個示例中,兩者都已經為真)
string | number
string | number
不能分配給MultiType | null
MultiType | null
因為number
和string
都不能賦值給'x' | 'y' | null
'x' | 'y' | null
如果key
是'multiType'
則'multiType'
'x' | 'y' | null
但是出於某種原因,在你的第一個例子中,TypeScript只是在第一個“錯誤”的情況下停止並給你這個錯誤(即使已經有兩個錯誤了)。
在第二種情況下,您可能已經看到了相同的錯誤消息,因為類型的不兼容性仍然存在,似乎推理更深入並且告訴您問題比這更深。 至於為什么錯誤消息的格式是這樣的,我真的不知道,我想這將需要更深入地了解編譯器如何在這里推斷出事物。 最后,編譯器是正確的,但錯誤消息可能更清楚。
對於您的第二個問題, never
類型的文檔說:
never
類型是每種類型的子類型,並且可分配給每種類型
因此,您可以將value
指定為never
類型,並將其分配給您的data
。 因為它永遠不會發生。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.