iT邦幫忙

2024 iThome 鐵人賽

DAY 6
0
JavaScript

TypeScript 初學者也能看的學習指南系列 第 6

TypeScript 初學者也能看的學習指南 06 - Array 陣列

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20240916/20149362jpfFzjorXj.png

本篇要來講的是 Object Types 中的 array,你將了解到在 TypeScript 中「陣列」的型別註釋寫法、如何去定義「多維陣列」、「構造函示」所創建的陣列等


陣列的型別註釋

若還不了解型別註釋,請看這篇 型別系統: 型別註釋 & 型別推斷
陣列的型別註釋有以下三種寫法:

  1. 型別[]

語法:型別 + 方括號,例如: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 編譯器會進行「型別推斷」,自動判斷型別
但如果新增不符合型別的值一樣也會跳出錯誤
https://ithelp.ithome.com.tw/upload/images/20240909/20149362p5seLMBNl4.png
https://ithelp.ithome.com.tw/upload/images/20240909/201493627uqPtMSjV8.png

那如果是值有混合一個以上的型別呢?
它會被推論為字串和數字的聯合型別(string | number)[],只允許陣列中的值為 stringnumber
https://ithelp.ithome.com.tw/upload/images/20240916/20149362IZ0jn5CcWD.png

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'

  1. Array<型別> 陣列泛型

語法:這是陣列泛型的表示方式, Array 後用角括號包住型別,例如:Array<number>

const arr3: Array<number> = [1, 2, 3];
const strArr: Array<string> = ["hey", "yo"];

關於泛型,之後會介紹到,可以先參考保哥的電子書


  1. 使用 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 aliasinterface 取代更為合適也更好維護

// 定義一個電影院的座位陣列
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');

情境四:陣列中的物件

有時候資料傳回來,常是陣列包物件的結構,這時能怎麼命名呢?

以下舉幾種方法:

  1. 直接定義
let arrayOfObjects: { id: number; name: string; }[] = [
  { id: 1, name: 'Item 1' },
];
  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 上喔

References


上一篇
TypeScript 初學者也能看的學習指南 05 - Object 物件
下一篇
TypeScript 初學者也能看的學習指南 07 - Tuple 元組
系列文
TypeScript 初學者也能看的學習指南30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言