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

 

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