iT邦幫忙

2024 iThome 鐵人賽

DAY 10
0
JavaScript

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

第10關:Concat!TypeScript 陣列拼圖:合併出完美結局

  • 分享至 

  • xImage
  •  

第10關:Concat

關卡簡介

Implement the JavaScript Array.concat function in the type system. A type takes the two arguments. The output should be a new array that includes inputs in ltr order

實現 JavaScript 中的 Array.concat 函數功能,並且在 TypeScript 的型別系統中完成這個功能。Concat 這個型別接收兩個陣列作為參數,並返回一個依次包含這兩個陣列元素的新陣列。

任務說明:

type Result = Concat<[1], [2]> // expected to be [1, 2]

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

const tuple = [1] as const

type cases = [
  Expect<Equal<Concat<[], []>, []>>,
  Expect<Equal<Concat<[], [1]>, [1]>>,
  Expect<Equal<Concat<typeof tuple, typeof tuple>, [1, 1]>>,
  Expect<Equal<Concat<[1, 2], [3, 4]>, [1, 2, 3, 4]>>,
  Expect<Equal<Concat<['1', 2, '3'], [false, boolean, '4']>, ['1', 2, '3', false, boolean, '4']>>,
]

冒險指南:

未來補充😭

通關方式:

解法:

type Concat<T extends readonly any[], U extends readonly any[]> = [...T, ...U];

細節分析:

  • Generic Parameters (泛型參數) <T extends readonly any[], U extends readonly any[]>

    • T extends readonly any[]
      這個泛型參數 T 是一個只讀的陣列(readonly 表示陣列中的元素不可修改),並且陣列元素的型別是 any,即它可以包含任意型別的元素。extends 表示一個型別約束,這裡要求 T 必須是一個陣列。這確保了只能將符合陣列型別的資料傳入 T
    • U extends readonly any[]
      T 相同,U 也是一個只讀的任意型別陣列。這個參數與 T 一起用來代表我們需要合併的第二個陣列。
  • Spread Operator (展開運算符) ...T...U

    • ...T 和 ...U 是陣列展開運算符,在型別系統中,它會將陣列 TU 中的所有元素解構並放入一個新的陣列。
    • 當我們將 TU 都展開,並合併成 [...],這就生成了一個包含 TU 所有元素的新陣列。
  • 輸出型別:

    • 這個 Concat 型別的最終結果是一個新陣列型別,它會依次包含 TU 中的所有元素,順序保持不變。 例如,Concat<[1, 2], [3, 4]> 的結果是 [1, 2, 3, 4]

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

其他補充:

有沒有 readonly 實際上差在哪?

  1. With readonly:
type Concat<T extends readonly any[], U extends readonly any[]> = [...T, ...U];

// Example usage
const array1 = [1, 2] as const; // `as const` makes it readonly
const array2 = [3, 4] as const;

type Result = Concat<typeof array1, typeof array2>; // Result is inferred as [1, 2, 3, 4]

// Trying to modify array1 or array2 will cause an error
// array1[0] = 10; // Error: Cannot assign to '0' because it is a read-only property.
// array2.push(5); // Error: Property 'push' does not exist on type 'readonly [3, 4]'.
  1. Without readonly:
type Concat<T extends any[], U extends any[]> = [...T, ...U];

// Example usage
const array1 = [1, 2]; // Regular array
const array2 = [3, 4];

type Result = Concat<typeof array1, typeof array2>; // Result is inferred as [1, 2, 3, 4]

// Now we can modify array1 or array2 without errors
array1[0] = 10; // This is allowed; array1 is now [10, 2]
array2.push(5); // This is allowed; array2 is now [3, 4, 5]

console.log(array1); // Output: [10, 2]
console.log(array2); // Output: [3, 4, 5]

關鍵字補給:

  • Any : 未來補充 😭
  • Unknown : 未來補充 😭

總結:

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


上一篇
第9關:If!TypeScript可惜沒如果:boolean世界,非黑即白
下一篇
第11關:Includes!TypeScript 包青天:元素不見立刻判決,無情 false
系列文
TypeScript Type Challenges 冒險篇章:30 天闖關之旅,type 簡單了?你確定?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言