Typesctipt 定義二維列表的型別
在平時需求中我們經常會遇到定義定長陣列型別的需求
比如一個 9x9 的棋盤 model:
let board = [ [0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0], ]; 複製程式碼
我們知道 typescript 是支援設定一個數組型別的,那有沒有辦法設定一個定長的陣列型別呢?
本體
首先我們來看一個簡單的例子,定義一個 iMArray 的陣列並把它的型別置為 number[]
let iMArray: number[] = [0, 1]; 複製程式碼
這是這種型別有個弊端,那就是我們並沒法限制陣列的長度
iMArray.length = 3; iMArray[3] = 1; 複製程式碼
其中一種方式是使用元組來定義型別
let iMArray: [number, number] = [0, 1]; 複製程式碼
可以看到當我想對超出限定範圍下標的陣列元素進行賦值時, typescript 會給我們提示異常.
// boom iMArray[3] = 1; 複製程式碼

可是假如我們想定義一個長度限制在50的陣列呢?難不成要寫50遍 number?
不,解決辦法還是有的,在 Typescript 3.0 中引入一個新的特性叫 元組展開
假如我們想定義一個長度為 50 的陣列, 我們只要這樣寫:
type Tuple50<TItem> = [TItem, ...TItem[]] & { length: 50 }; let iMArray: Tuple50<number> = [0,...,50]; 複製程式碼
可以看到,結合元組展開以及交叉型別,我們成功定義了一個長度為50,陣列元素為 number 的陣列.
回到前言提到的那個棋盤類,我們就可以這樣定義一個9x9的棋盤型別了.
type Tuple9<TItem> = [TItem, ...TItem[]] & { length: 9 }; type TypeBoard<T> = Tuple9<Tuple9<T>>; let board: TypeBoard<number> = [ [0, ..., 9], ... [0, ..., 9], ] 複製程式碼
最後給一個封裝好的 Tuple 類
type Tuple<TItem, TLength extends number> = [TItem, ...TItem[]] & { length: TLength }; 複製程式碼