iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0
JavaScript

TypeScript Type Challenges 冒險篇章:30 天闖關之旅,type 簡單了?你確定?系列 第 20

第20關:Pop!TypeScript Popping 舞王:震掉最後一個元素

  • 分享至 

  • xImage
  •  

第20關:Pop

關卡簡介

Implement a generic Pop<T> that takes an Array T and returns an Array without it's last element.

實現一個通用的 Pop<T>,它接收一個陣列 T 並返回去掉最後一個元素的陣列。

任務說明:

type arr1 = ['a', 'b', 'c', 'd']
type arr2 = [3, 2, 1]

type re1 = Pop<arr1> // expected to be ['a', 'b', 'c']
type re2 = Pop<arr2> // expected to be [3, 2]

接下來,你的任務是讓下面的type cases測試通過:

type cases = [
  Expect<Equal<Pop<[3, 2, 1]>, [3, 2]>>,
  Expect<Equal<Pop<['a', 'b', 'c', 'd']>, ['a', 'b', 'c']>>,
  Expect<Equal<Pop<[]>, []>>,
]

冒險指南:

從以下幾個方向來思考:

  • 型別推斷 (Type Inference):使用 infer 來從泛型中推導型別。
  • 陣列解構與尾部推斷 (Array Destructuring with Inference):我們的目標是從陣列中分離出最後一個元素。透過 TypeScript 的 ... (Spread Syntax),可以將陣列分成前面的部分和最後一個元素,再用 infer 來推斷該最後元素的型別。
    • 例如: T extends [...infer Rest, infer Last]:這樣的語法能夠將陣列解構,把最後一個元素取出並賦值給 Last,而前面的元素則賦值給 Rest。無論陣列的長度如何,這種方法都適用。
  • 邊界情況處理 (Edge Case Handling):記得要考慮空陣列的情況。當陣列為空時,應該返回空陣列,避免錯誤發生。

通關方式:

解法1:

type Pop<T extends any[]> = T extends [...infer F, any] ? F : T 

細節分析:

  • 條件型別 (Conditional Types):條件型別允許我們根據型別是否符合某個條件來執行不同的邏輯操作。在這裡,T extends [...infer F, any] 被用來檢查 T 是否符合「一個陣列,且其最後一個元素可以被推斷」的條件。
    • T extends [...infer F, any] 表示 T 是一個任意長度的陣列,並且最後一個元素可以是任意型別 (any)。如果 T 符合這個結構,則推斷出前面的部分 F,這正是我們需要返回的結果。
    • 如果條件為真,則返回前面的部分 F;如果條件為假(例如,T 是空陣列),則返回 T 本身,這處理了邊界情況。
  • 型別推斷 (Type Inference):使用 infer 關鍵字來從型別 T 中推斷前半部分的陣列。這是 TypeScript 在處理不確定長度的陣列或元組時一個常見的技巧。
    • infer F 會嘗試推斷出去掉最後一個元素後的陣列部分 F,這就是我們要保留的部分。
      省略元素 (Omitting Elements):T extends [...infer F, any] 的結構通過 ...infer F 捕捉陣列的前面部分,並且忽略最後一個元素(any)。這使我們能夠處理不同長度的陣列,無需關注具體的長度或元素內容。
    • 使用 any 作為最後一個元素的占位符,因為我們對它的具體型別不關心,只需要知道它存在並且我們要忽略它。
  • 邊界情況 (Edge Case):當 T 是空陣列時,T 不符合 T extends [...infer F, any] 的條件,因此會返回 T 自身,這避免了對空陣列進行不必要的操作,並確保結果符合預期。

這樣,我們就能順利通過測試啦 🎉 😭 🎉

額外補充:
https://ithelp.ithome.com.tw/upload/images/20241004/20168789wIhYeX2jsS.png

總結:

本次介紹了 Pop 的實作,下一關會挑戰 Trim Left,期待再相見!


上一篇
第19關:Last of Array!TypeScript 吊車尾:漩渦鳴人來也
下一篇
第21關:Trim Left!TypeScript 左撇剪刀手:移除字串開頭空白
系列文
TypeScript Type Challenges 冒險篇章:30 天闖關之旅,type 簡單了?你確定?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言