includes

作者: sweetBoy_9126 | 来源:发表于2022-07-22 22:00 被阅读0次

测试 case

type cases = [
  Expect<Equal<Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Kars'>, true>>,
  Expect<Equal<Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Dio'>, false>>,
  Expect<Equal<Includes<[1, 2, 3, 5, 6, 7], 7>, true>>,
  Expect<Equal<Includes<[1, 2, 3, 5, 6, 7], 4>, false>>,
  Expect<Equal<Includes<[1, 2, 3], 2>, true>>,
  Expect<Equal<Includes<[1, 2, 3], 1>, true>>,
  Expect<Equal<Includes<[{}], { a: 'A' }>, false>>,
  Expect<Equal<Includes<[boolean, 2, 3, 5, 6, 7], false>, false>>,
  Expect<Equal<Includes<[true, 2, 3, 5, 6, 7], boolean>, false>>,
  Expect<Equal<Includes<[false, 2, 3, 5, 6, 7], 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>>,
]
  • template.ts
type Includes<T extends readonly any[], U> = any

js 实现

方式1

const includes = (T: unknown[], U: unknown) => {
  let result = false
  for(let i = 0; i < T.length; i++) {
    if (T[i] === U) {
      result = true
    }
  }
  return result
}

问题:
我们遍历数组必须要使用 In 关键字,但是in关键字只能在对象里使用,而我们又不需要返回对象,所以这种方案不适合

方式2

const includes2 = (T: unknown[], U: unknown) => {
  if (T.length === 0) {
    return false
  }
  const [first, ...reset] = T
  if (first === U) {
    return true
  } else {
    includes2(reset, U)
  }
}

步骤

  1. 取出第一项,如果第一项等于 U 返回 true
  2. 不等于就递归

ts 实现

版本1

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

问题:
Expect<Equal<Includes<[boolean, 2, 3, 5, 6, 7], false>, false>>,
上面对于boolean 类型最为 First 的时候,因为 boolean 就相当于 false | true 的联合类型,First 又是一个变量类型,所以会走分布式条件语句就有得到 false => false = true true => false = false 所以结果是 true | false 也就是 boolean 解决方法给 First 和 U 都加一层[]

版本2

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

问题:
上面的代码虽然boolean的解决了,但是对于
{ a: 'A' } extends { readonly a: 'A' } => true
true extends boolean => true
而我们的用例里是期望 false

版本3

// 使用 IsEqual
type IsEqual<A, B> = (<T>() => T extends A ? 1 : 2) extends (<T1>() => T1 extends B ? 1 : 2) ? true : false
type Includes<T extends readonly any[], U> = T extends [infer First, ...infer Reset] ? IsEqual<First, U> extends true ? true : Includes<Reset, U> : false

相关文章

网友评论

      本文标题:includes

      本文链接:https://www.haomeiwen.com/subject/kkdvirtx.html