本篇要來講的是 Object Types 中的 array,你將了解到在 TypeScript 中「陣列」的型別註釋寫法、如何去定義「多維陣列」、「構造函示」所創建的陣列等
若還不了解型別註釋,請看這篇 型別系統: 型別註釋 & 型別推斷
陣列的型別註釋有以下三種寫法:
型別[]
語法:型別 + 方括號,例如:
number[]
來看看下方的例子會更清楚,這裡新增了一個 arr1
, arr2
並規定陣列裡的值只能是數字
如果對陣列新增不符合型別的值就會跳出錯誤
const arr1: number[] = [1, 2, 3]; // 數字 array
arr1.push('1'); // ❌ Argument of type 'string' is not assignable to parameter of type 'number'.
const arr2: string[] = ['1', '2', '3']; // 字串 array
那不加型別可以嗎?
當然可以!TS 編譯器會進行「型別推斷」,自動判斷型別
但如果新增不符合型別的值一樣也會跳出錯誤
那如果是值有混合一個以上的型別呢?
它會被推論為字串和數字的聯合型別
: (string | number)[]
,只允許陣列中的值為 string
或 number
const mixedArr = [1, '2', 3, 4];
mixedArr.push('5');
mixedArr.push(6)
// mixedArr.push({a: 1}) // ❌ Argument of type '{ a: number; }' is not assignable to parameter of type 'string | number'.
// mixedArr.push(true) // ❌ Argument of type 'boolean' is not assignable to parameter of type 'string | number'
Array<型別>
陣列泛型語法:這是
陣列泛型
的表示方式, Array 後用角括號包住型別,例如:Array<number>
const arr3: Array<number> = [1, 2, 3];
const strArr: Array<string> = ["hey", "yo"];
關於泛型,之後會介紹到,可以先參考保哥的電子書
使用 interface(介面)
語法:interface XXXX { ... }
interface 的名稱一般會大寫開頭,類似於 Class的概念
interface StringArray {
[index: number]: string; // 索引簽名
length: number; // 原有的陣列屬性
}
console.log(myArray) // ["Hello","World"]
console.log(myArray[0]); // Hello
console.log(myArray.length); // 2
console.log(myArray.foo); // ❌ Property 'foo' does not exist on type 'StringArray'.
console.log(myArray.push("foo")); // ❌ Property 'push' does not exist on type 'StringArray'.
[index: number]
是「索引簽名」 的語法,代表 可以透過索引(數字)來存取,後面的 :string
代表透過索引取到的元素型別為字串length: number
取得陣列長度,型別為數字雖然你可以使用介面來定義陣列,但這種方式並不會自動提供陣列的處理方法,如 push()、pop()、map() 等
就算可以在介面中手動定義這些方法,但還是不比直接使用陣列型別來得方便
不過有一種情況例外,那就是它常用來表示「類陣列物件(Array-like Object)」
以下提供幾個情境範例:
語法:
型別[][]
,ex.string[][]
,幾維陣列就有幾個[]
二維以上的陣列同時也牽涉到較複雜的資料結構,可以使用 type alias
或 interface
取代更為合適也更好維護
// 定義一個電影院的座位陣列
const cinemaSeats: boolean[][] = [
[false, false, false, false],
[false, false, true, true],
];
其實就是上面提到的
可以搭配使用 Union Type (聯合型別)
,關鍵語法 |
去連接各個型別
const mixedArr2: (string | number)[] = [1, 2, 3]; // arr1 裡的值可以是「字串」或「數字」
函式回傳一個既包含字串又包含數字的陣列
function getData(): Array<string | number> {
return [1, "two", 3, "four"];
}
Array 構造函式 new Array() 創建的陣列也可以使用
new Array()的參數有以下三種形式,順便來複習一下 JavaScript:
不傳入
:會建立一個空陣列傳入一個代表陣列長度的數字
:會建立一個以此數字為陣列長度的陣列傳入多個參數
:會建立一個包含指定元素的陣列let numArr: Array<number> = new Array(); // 只能接受數字的空陣列
numArr.push('test') // ❌ ...
let fixedArr: boolean[] = new Array(2); // 只能接受布林且長度為 2 的陣列
console.log(fixedArr); // [,]
let strNewArr: string[] = new Array('Hi', 'Mike');
有時候資料傳回來,常是陣列包物件的結構,這時能怎麼命名呢?
以下舉幾種方法:
直接定義
let arrayOfObjects: { id: number; name: string; }[] = [
{ id: 1, name: 'Item 1' },
];
使用 interface
interface MyObject {
id: number;
name: string;
memo?: string; // 可選屬性
}
let arrayOfObjects: MyObject[] = [
{ id: 1, name: 'Item 1', memo: 'test' },
];
arrayOfObjects.push({ id: 2, name: 'Item 2' });
console.log(arrayOfObjects); // 印出兩個物件
你還有想到什麼方法嗎?歡迎留言分享~
每天講的內容有推到 github 上喔