Type Challenges Notes - Easy 篇
2021 / 5 / 10
前言
這是一篇關於 Type Challenges 作答時的一些筆記,「Type Challenges」 是什麼呢?有鑒於 TS 在前端世界裡越來越盛行,似乎已成為熱門必備技能,而 TS 中的型別系統也是日益完備與強大,除了基本的使用 type / interface 已經讓我嗅到了不足的味道,是時候來腳踏實地的練習運用 TS 型別系統了!
本文
在 Type Challenges 該 Repo 中的 README 中就有提供一份由難易度分類的清單可供挑戰,並且作答時會有建立好的 TS Playground 使用,也有 github issues 中的其他參與者答案可以參考學習,可謂是非常貼心!
Easy
Pick
- 答案:
type MyPick<T, K extends keyof T> = { [P in K]: T[P]; }
- 筆記:
首先約束K
須為T
的 key,接著定義 Mapped Type 令 keyP
在K
之中且 value 為T[P]
Readonly
- 答案:
type MyReadonly<T> = { readonly [K in keyof T]: T[K]; }
- 筆記:
定義 Mapped Type,先加上 readonly,令 keyK
為 keyofT
,value 為T[K]
Tuple to Object
- 答案:
type TupleToObject<T extends readonly any[]> = { [K in T[number]]: K; }
- 筆記:
由於T
為唯讀的陣列因此可推斷為 TS 中的 tuple,這就代表T[number]
是可以推斷對應的值,所以令 Mapped Type 的 key 為K
並存在於T[number]
之中,且令 value 為K
First of Array
- 答案:
type First<T extends any[]> = T[number] extends never ? never : T[0]
- 筆記:
先約束若T[number]
為 never,即陣列為空應返回never
,否則返回T[0]
Length of Tuple
- 答案:
type Length<T extends readonly any[]> = T['length']
- 筆記:
讓T
限制為唯讀any[]
,讓型別推斷可推斷出T['lemgth']
Exclude
- 答案:
type MyExclude<T, U> = T extends U ? never : T
- 筆記:
若T
包含於U
,返回never
否則返回T
Awaited
- 答案:
type Awaited<P> = P extends Promise<infer T> ? T : never
- 筆記:
使用 infer 在條件式保持推斷,在這題用來判斷型別是否繼承Promise
並推斷Promise<T>
的T
應該為什麽型別
If
- 答案:
type If<C extends boolean, T, F> = C extends true ? T : F
- 筆記:
先約束C
為boolean
及非true
則false
,後面就簡單了,C
為true
返回T
,反之為F
Concat
- 答案:
type Concat<T extends any[], U extends any[]> = [...T, ...U]
- 筆記:
約束T
、U
為 array / tuple,就可以使用概念接近擴展符號的方法去串起T
、U
所有型別
Includes
- 答案:
type Includes<T extends readonly any[], U> = U extends T[number] ? true : false;
- 筆記:
T
被約束為readonly any[]
(tuple),利用此點可進行U extends T[number]
條件推斷
後記
在這篇先整理跟作答完 Easy
難度的所有題目,對於原本只會使用基礎型別的我來說算是滿不錯的暖身練習,也算是基本的摸了摸 Mapped Type
、Conditional Type
等等的知識,截至為止也做了一部分的 Medium
難度的題目,難度一下就提了上來(汗,不過也讓我刷新眼界,TS 的型別系統真的很酷 😄