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>
递归处理。