Skip to main content

Includes

题目

在类型系统里实现 JavaScript 的 Array.includes 方法,这个类型接受两个参数,返回的类型要么是 true 要么是 false

举例来说,

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

题目来源:https://tsch.js.org/898/zh-CN

解答

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

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

解题的重点有两个:

  • 判断两个类型相等,需要实现Equal
  • 逐个拆解类型数组T,将单个项取出来比较

Equal

<T>() => T extends X ? 1 : 2(<T>() => T extends Y ? 1 : 2): 取出比较参数的类型。
如果X,Y不相等,则第1个表达式取到的数字,和第2个表达式取到的数字不一样。
原因是T只能是一种类型。(1只脚不能同时踏入两条河流的哲学问题:))

逐个取出数组中的值

T extends [infer K, ...infer R]用于提取数组中的值,并使用Equal<U, K>进行比较。
如果不相等,则用Includes<R, U>递归处理。