TypeScript 複習與進階三部曲 (3) – TypeScript 類型體操

前言

在 第一部 – 把 TypeScript 當強類型語言使用 和 第二部 – 把 TypeScript 當編程語言使用 後, 我們幾乎已經把 TypeScript 的招數學完了.

第三部就要開始做練習題了, 這樣才能融會貫通.

記得, 做練習題只是單純爲了更理解 TypeScript 這門語言. 在簡單的項目中是沒有必要的. 我們可以使用各種 Ultility 庫 (e.g. type-festts-toolbelt) 來幫助我們完成業務代碼.

 

type-challenges

社區已經提供了各種題目. 項目 : Github – type-challenges

一共分 4 個等級, 全部擼一遍就可以了

選擇題目後會看見

然後開始做題, 會進入到 TypeScript Playground

 

上半段是題目講解, 中間是我們回答的地方, 下面是測試代碼, 答案錯誤它會顯示紅線, 正確則紅線消失

做題

 

 

常用小技巧

這裏記入一些常用到的技巧

1. Tuple to Union

type Tuple1 = [string, number];
type Union1 = Tuple1[number]; // string | number

2. Looping Tuple

type Includes<T extends readonly any[], U> = T extends [infer First, ...infer Rest] 
? Equal<U, First> extends true 
  ? true 
  : Includes<Rest, U>
: false;

通過 extends + infer + rest + recursive 可以 loop Tuple 返回一個 Type.

 

高級技巧

1. Equal

在 type-challenges 的測試代碼中, 用到了一個叫 Equal 的 Ultility.

我們之前有講過, TypeScript 只有 extends 沒有 equal. 比如下面這題

type Yes = { age: 11 } extends {} ? true : false; // true

因爲 { age: 11 } 是 "一種" {} 所以結果是 true

那如果我們想要 "Equal" 呢?

可以這麼寫

type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false

我是沒看懂的. 有興趣的朋友可以看這裏 Github – [Feature request]type level equal operator #27024

大致意思是, 當 conditional 遇上 泛型 T 產生了化學反應, 所以就有了 equal 的功能. 

 

難度題目解析

1. Easy – Includes

第一題把我難到的是 includes (它的 level 是 easy...)

題目是實現 array.includes 功能

 type isPillarMen = Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Dio'> // expected to be `false`

第二個參數在 array 內就返回 true, 否則 false.

錯誤的思路

我第一個想到的解法是

type Includes<T extends readonly any[], U> = U extends T[number] ? true : false;

把 Tuple 換成 Union 然後 extends, 這招只能 cover 默寫場景

因爲 { a: 'A' } extends {} 是 true. 而這裏要的是 equal 而不是 extends

正解

type Includes<T extends readonly any[], U> = T extends [infer First, ...infer Rest] 
? Equal<U, First> extends true 
  ? true 
  : Includes<Rest, U>
: false;

裏頭用了幾個技巧.

1. looping Tuple, 它是通過 extends + infer + rest + recursive 來實現的

2. Equal Utility, 這個是 type-challenges 提供的 Utility

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章