[TypeScript] Type Challenges #898 - Includes

89 阅读1分钟

题目描述

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

例如:

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

题解

// ============= Test Cases =============
import type { EqualExpect } from './test-utils'

type cases = [
  Expect<Equal<Includes<['Kars''Esidisi''Wamuu''Santana'], 'Kars'>, true>>,
  Expect<Equal<Includes<['Kars''Esidisi''Wamuu''Santana'], 'Dio'>, false>>,
  Expect<Equal<Includes<[123567], 7>, true>>,
  Expect<Equal<Includes<[123567], 4>, false>>,
  Expect<Equal<Includes<[123], 2>, true>>,
  Expect<Equal<Includes<[123], 1>, true>>,
  Expect<Equal<Includes<[{}], { a'A' }>, false>>,
  Expect<Equal<Includes<[boolean23567], false>, false>>,
  Expect<Equal<Includes<[true23567], boolean>, false>>,
  Expect<Equal<Includes<[false23567], false>, true>>,
  Expect<Equal<Includes<[{ a'A' }], { readonly a'A' }>, false>>,
  Expect<Equal<Includes<[{ readonly a'A' }], { a'A' }>, false>>,
  Expect<Equal<Includes<[1], 1 | 2>, false>>,
  Expect<Equal<Includes<[1 | 2], 1>, false>>,
  Expect<Equal<Includes<[null], undefined>, false>>,
  Expect<Equal<Includes<[undefined], null>, false>>,
]


// ============= Your Code Here =============
type Includes<T extends readonly any[], U> =
  T extends [infer A, ...infer B]
  ? Equal<A, U> extends true
    ? true
    : Includes<B, U>
  : false

使用T extends [infer A, ...infer B]对数组T进行类型推断,将T的第一个元素存储为A,剩余元素存储为B

使用Equal<A, U>来比较AU是否相等,如果相等,返回true

如果不相等,递归调用Includes<B, U>检查剩余元素,直到找到匹配元素或遍历完整个数组