iT邦幫忙

2024 iThome 鐵人賽

DAY 6
0

擴充型別

1. 元祖型別(Tuple Types)

前一篇文章在介紹陣列型別時,有稍微帶到元組的概念。可以將元組型別(Tuple Types)理解為工作方式類似於數組的概念,但有一些額外的注意事項:

  • 元組中的元素數量是固定的。
  • 元素的類型是已知的且可以不同。
// 初始宣告
let skills: [string, number] = ['TypeScript', 100];

// 錯誤使用情形 1:多於定義的元素數量
let skills: [string, number] = ['TypeScript', 100, 88];

// 錯誤使用情形 2:元素類別不符合原定義
let skills: [string, number] = [100, 'TypeScript'];

另外也有個有趣且實用的使用方式,就是使用元組來定義顏色的 RGBA 值。在 TypeScript 3.0 後的版本,元組型別支援使用後綴問號 ? 的元素內容。所以可以將其應用在顏色的透明度(Alpha)值的可選狀況,當有需要指定時再傳入:

let favoriteColor, hateColor: [number, number, number, number?];
favoriteColor = [255, 153, 0, 0.5];
hateColor = [255, 255, 0];

2. 枚舉型別(Enum Types)

枚舉型別(Enum Types)用來定義一組具名的常數集合,這些常數可以是數字或字串。枚舉型別提高了程式碼的可讀性和可維護性,因為每個值都是唯一且具名的。
特別的是枚舉型別(Enum Types)在編譯成 JavaScript 後,其實是一包物件,而且會自動生成數字索引給每個常數。

而如果要定義枚舉,則需要執行下列步驟:

  • 使用 enum 關鍵字,後面接著枚舉名稱。
  • 定義枚舉的常數值。

實際來看一下最基礎的宣告範例:

enum Month {
    Jan,
    Feb,
    Mar,
    Apr,
    May,
    Jun,
    Jul,
    Aug,
    Sep,
    Oct,
    Nov,
    Dec
};
  • 枚舉型別常用來提升程式碼的可讀性。例如,以下函式會判斷傳入的月份是否屬於夏季:
// 定義一個指定某幾個月份為夏天的函式
function isItSummer(month: Month) {
  let isSummer: boolean;
  switch (month) {
    case Month.Jun:
    case Month.Jul:
    case Month.Aug:
      isSummer = true;
      break;
    default:
      isSummer = false;
      break;
  }
  return isSummer;
}

// 可以實際測試某個月分是否為夏天
console.log(isItSummer(Month.Jun)); // true

這種枚舉應用之所以可以有效可讀性和可維護性,是因為如果今天改用數字枚舉去列出 1~12,那麼並無法清楚的知道它真實代表什麼,而使用月份的簡寫,更可清晰地辯讀。

  • 自動生成的數字索引有什麼作用?
    其實實際把 Month 這個枚舉型別印出來會得到以下內容,就和一般陣列一樣,從 0 開始索引。
{
  '0': 'Jan', 
  '1': 'Feb', 
  '2': 'Mar', 
  '3': 'Apr', 
  '4': 'May', 
  '5': 'Jun', 
  '6': 'Jul', 
  '7': 'Aug', 
  '8': 'Sep', 
  '9': 'Oct', 
  '10': 'Nov',
  '11': 'Dec',
  Jan: 0,     
  Feb: 1,     
  Mar: 2,     
  Apr: 3,     
  May: 4,
  Jun: 5,
  Jul: 6,
  Aug: 7,
  Sep: 8,
  Oct: 9,
  Nov: 10,
  Dec: 11
}

而我們可以善用這個數字索引來實際測試輸入索引值數字,而不是輸入我們先前定義好的常數:

console.log(isItSummer(1)); // true

對,沒錯!它可以正常運行!雖然我沒定義它,但因為以上原理它自動產生,並轉換為 value,所以當我將數字當作參數傳入 function,還是可以運行。

當然,以我們常規的了解,會覺得不對阿,我們的月份式從1月開始,而不是索引值的起始點0,這會讓對應上出了問題,明明 Jan 是代表1月,可是因為索引從0開始,全部都亂了套。

但這是有方式可以破解的,只要在第一個常數後面指定它的值為1即可:

enum Month {
    Jan = 1,
    Feb,
    Mar,
    Apr,
    May,
    Jun,
    Jul,
    Aug,
    Sep,
    Oct,
    Nov,
    Dec
};

宣告完成後,再打印一次結果確認,會發現順利對應上了:

{
  '1': 'Jan',
  '2': 'Feb',
  '3': 'Mar',
  '4': 'Apr',
  '5': 'May',
  '6': 'Jun',
  '7': 'Jul',
  '8': 'Aug',
  '9': 'Sep',
  '10': 'Oct',
  '11': 'Nov',
  '12': 'Dec',
  Jan: 1,
  Feb: 2,
  Mar: 3,
  Apr: 4,
  May: 5,
  Jun: 6,
  Jul: 7,
  Aug: 8,
  Sep: 9,
  Oct: 10,
  Nov: 11,
  Dec: 12
}

結語

擴充型別如元組和枚舉提供了強大的工具來更精確地描述資料結構,從而提升了程式碼的可讀性和可維護性。掌握這些進階型別後,能夠應對更多複雜的情境,進一步提高開發效率。


參考資源:
TypeScript Enum


上一篇
Day05:TypeScript 的陣列型別(Array Types)
下一篇
Day07:TypeScript 的函式型別(Function Types and Parameters)
系列文
用 TypeScript 重新定義前端開發:30 天的實踐與思考30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言