iT邦幫忙

2022 iThome 鐵人賽

DAY 9
0
Modern Web

Hello TypeScript 菜鳥系列 第 9

Day 8. TypeScript 參考型別:Tuple

  • 分享至 

  • xImage
  •  

Tuple (中文好像可以稱作 元祖),是Array(陣列)的一種變形,也是array的子型別,不一樣的是,Array是不固定長度,而Tuple則需要事先固定長度並依序指定包含的元素型別,也就是說Tuple的元素不可任意增加元素數量且儲存元素須依序符合事先定義的型別,例如:

let control: [string, boolean] = ["light", false];

需要注意的是,Tuple需要按照型別順序來賦值,如果沒有按順序賦值就會出現編譯錯誤:

let controller: [string, boolean] = [false, "light"];

當然,Tuple可儲存的元素也包含其他參考型別,例如儲存Array型別的元素:

let member: [number, string][] = [[1, 'Alice'], [2, 'Bob], [3, Crow]]:

既然Tuple有類似於Array的用法,那麼問題來了,Tuple通常可以在什麼時候應用?

一般來說,Tuple是已知某些變數是固定長度、具有特定順序(或特定型別順序)以及元素之間彼此有關聯的時候使用,例如在顏色可以用rgb三種原色且各自以0~255的數值表示,因為三原色只有三種,就可以用Tuple來表示:

let rgb: [number, number, number] = [255, 255, 255];

顏色除了可以用rgb來表示,有時也會用rgba來指定顏色,但rgba的alpha值不是必填選項,此時再借助之前所講過的 optional operator 來描述非必填元素:

let rgba: [number, number, number, number?] = [255, 255, 255];
let gray: [number, number, number, number?] = [0, 0, 0, 0.5];

為了增加程式碼的可閱讀性,使用Tuple也可以替每個元素命名,沿用前面rgb的例子:

let rgb: [number, number, number] = [r: 255, g: 255, b: 0];

因為Tuple也是一種array,所以除了可以用索引取值,同樣能對Tuple解構(destructuring),或者使用array的方法:

let color: [number, number, number] = [255, 255, 0];

// Get element via index
console.log(color[0]); // 255

// Destrcture tuple
let [r, g, b] = color;
console.log(r); // 255

// Pop element
let e = color.pop();
console.log(e); // 0

不過上面都是用 let 來宣告一個Tuple,
使用且可以更新原來儲存的元素,像是第一個例子:

let member: [number, string][] = [[1, 'Alice'], [2, 'Bob'], [3, Crow]];
member.push([10, David]); // [[1,'Alice'], [2, 'Bob'], [10, David]]

原來儲存的名單變得很容易被竄改,為了避免這種狀況,有時候比較好的做法是可以宣告一個 唯讀(read only) 的Tuple,也就是再加上一個 readonly 關鍵字,其宣告方式如下:

const member: readonly [id, string] = [[1, 'Alice'], [2, 'Bob'], [3, Crow]];
member.push([10, David]); // error

參考資料
TypeScript: JavaScript With Syntax For Types
TypeScript Tutorial
W3Schools Online Web Tutorials
TutorialsTeacher


上一篇
Day 7. TypeScript 參考型別:Object
下一篇
Day 9. TypeScript 參考型別:Enum
系列文
Hello TypeScript 菜鳥31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言