網站搜尋

TypeScript:為什麼當類型是空陣列和數據陣列的聯合時,存取一個項目時 undefined 不是一個選項


有人可以解釋這個嗎?

為什麼當類型是空陣列和資料陣列的聯合類型時,存取項目時 undefined 不是一個選項

type emptyArray = []
type accessEmptyArray = emptyArray[0] // returns undefined

type validData = {id:number, name:string}
type someData = validData[] | []

type test = someData[0] // returns type validData but could also be undefined

我假設我可以透過使用斷言來解決這個問題,但這會讓我的程式碼相當冗長。

我對這個問題感到相當驚訝,因為這似乎是一個很容易被忽視的問題,也是一種 TS 設計來解決的問題,但也許我還沒有想到我假設的工作方式可能存在的缺點

範例:遊樂場

答案#1

那是設計如此。

對類型進行索引訪問不會返回 undefined。

type array = Array<string>;
type firstItemType = array[0] // string;

答案#2

為了理解這一點,請注意:

type EmptyArray = []
type EmptyArray2 = never[]

`EmptyArray` 和 `EmptyArray2` 是相等的。在 TypeScript 中,空陣列被推斷為 `never[]`。

試試這個:

type EmptyArray = []
type Item = EmptyArray[number] // never

因此,空集合和非空集合的聯集看起來像這樣:

type ValidData = { id: number, name: string }

type Union = Array<ValidData> | never[]

type NonEmptyElement = Array<ValidData>[number] // ValidData
type EmptyElement = never[][number]             // never

type Result = Union[0] // ValidData | never -> ValidData

當你對空陣列/非空陣列進行聯集並試圖獲取第一個元素時,你基本上是在獲取 ValidData | never 的聯集,這等同於僅 ValidData。

如果你想知道為什麼 never 在任何聯合中都是毫無意義的,請看這個答案


關於以下錯誤:

type emptyArray = []

type accessEmptyArray = emptyArray[0] // returns undefined

這是因為 emptyArray 沒有任何元素,而 TypeScript 甚至不允許使用 0,然而,你仍然可以使用陣列的索引:

type accessEmptyArray = emptyArray[number] // never

這是因為 Array 有這個類型簽名:

interface Array<T> {
  [n: number]: T
}