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<[]>, []>>,
]
從以下幾個方向來思考:
T extends [...infer Rest, infer Last]
:這樣的語法能夠將陣列解構,把最後一個元素取出並賦值給 Last
,而前面的元素則賦值給 Rest
。無論陣列的長度如何,這種方法都適用。解法1:
type Pop<T extends any[]> = T extends [...infer F, any] ? F : T
細節分析:
T
是否符合「一個陣列,且其最後一個元素可以被推斷」的條件。
T
是一個任意長度的陣列,並且最後一個元素可以是任意型別 (any)。如果 T
符合這個結構,則推斷出前面的部分 F
,這正是我們需要返回的結果。T
是空陣列),則返回 T
本身,這處理了邊界情況。T
中推斷前半部分的陣列。這是 TypeScript 在處理不確定長度的陣列或元組時一個常見的技巧。
infer F
會嘗試推斷出去掉最後一個元素後的陣列部分 F
,這就是我們要保留的部分。T extends [...infer F, any]
的結構通過 ...infer F
捕捉陣列的前面部分,並且忽略最後一個元素(any)。這使我們能夠處理不同長度的陣列,無需關注具體的長度或元素內容。any
作為最後一個元素的占位符,因為我們對它的具體型別不關心,只需要知道它存在並且我們要忽略它。T
是空陣列時,T
不符合 T extends [...infer F, any]
的條件,因此會返回 T
自身,這避免了對空陣列進行不必要的操作,並確保結果符合預期。這樣,我們就能順利通過測試啦 🎉 😭 🎉
額外補充:
本次介紹了 Pop
的實作,下一關會挑戰 Trim Left
,期待再相見!