类型体操刷题系列(二十一)— Fibonacci/AllCombinations/GreaterThan

300 阅读2分钟

目的

Github上的类型体操,让你写出更加优雅的TS类型定义,以及探寻TS中我们不熟悉的只是,让我们开始TS的类型挑战把~2022希望通过更文的方式来督促自己学习,每日三题,坚持日更不断~~

题目大纲

  1. Medium Fibonacci
  2. Medium All Combinations
  3. Medium Greater than

01. Medium Fibonacci

题目要求

import { Equal, Expect } from '@type-challenges/utils'

type cases = [
  Expect<Equal<Fibonacci<3>, 2>>,
  Expect<Equal<Fibonacci<8>, 21>>,
]

我的答案

type Fibonacci<
  T extends number,
  C extends number[] = [number],
  V extends any[][] = [[number], [number]]
> = C["length"] extends T
  ? V extends [infer X, infer Y]
    ? X extends any[]
      ? X["length"]
      : 0
    : 0
  : V extends [infer X, infer Y]
  ? X extends any[]
    ? Y extends any[]
      ? Fibonacci<T, [...C, number], [Y, [...X, ...Y]]>
      : 0
    : 0
  : 0;

知识点

  1. 使用...进行数组的合并
  2. 通过length来对合并的数据长度进行求解

2. Medium All Combinations

题目要求

import { Equal, Expect } from '@type-challenges/utils'

type cases = [
  Expect<Equal<AllCombinations<''>, ''>>,
  Expect<Equal<AllCombinations<'A'>, '' | 'A'>>,
  Expect<Equal<AllCombinations<'AB'>, '' | 'A' | 'B' | 'AB' | 'BA'>>,
  Expect<Equal<AllCombinations<'ABC'>, '' | 'A' | 'B' | 'C' | 'AB' | 'AC' | 'BA' | 'BC' | 'CA' | 'CB' | 'ABC' | 'ACB' | 'BAC' | 'BCA' | 'CAB' | 'CBA'>>,
  Expect<Equal<AllCombinations<'ABCD'>, '' | 'A' | 'B' | 'C' | 'D' | 'AB' | 'AC' | 'AD' | 'BA' | 'BC' | 'BD' | 'CA' | 'CB' | 'CD' | 'DA' | 'DB' | 'DC' | 'ABC' | 'ABD' | 'ACB' | 'ACD' | 'ADB' | 'ADC' | 'BAC' | 'BAD' | 'BCA' | 'BCD' | 'BDA' | 'BDC' | 'CAB' | 'CAD' | 'CBA' | 'CBD' | 'CDA' | 'CDB' | 'DAB' | 'DAC' | 'DBA' | 'DBC' | 'DCA' | 'DCB' | 'ABCD' | 'ABDC' | 'ACBD' | 'ACDB' | 'ADBC' | 'ADCB' | 'BACD' | 'BADC' | 'BCAD' | 'BCDA' | 'BDAC' | 'BDCA' | 'CABD' | 'CADB' | 'CBAD' | 'CBDA' | 'CDAB' | 'CDBA' | 'DABC' | 'DACB' | 'DBAC' | 'DBCA' | 'DCAB' | 'DCBA'>>,
]

我的解答

type MyExclude2<T, R> = R extends T ? "" : R

type AllCombinations<S extends string> = S extends ""
  ? ""
  : S extends `${infer P}${infer T}`
  ?
      | P
      | AllCombinations<T>
      | `${AllCombinations<T>}${P}`
      | `${P}${AllCombinations<T>}`
  : "";

待办

  1. 这道题目只完成了一半,其中的3、4两个case是跑不过的,主要原因是缺失了对于BAC就是将P插入到T中的那种场景的枚举(后续补上)

3. Medium GreaterThan

题目要求

import { Equal, Expect } from '@type-challenges/utils'

type cases = [
  Expect<Equal<GreaterThan<1, 0>, true>>,
  Expect<Equal<GreaterThan<5, 4>, true>>,
  Expect<Equal<GreaterThan<4, 5>, false>>,
  Expect<Equal<GreaterThan<0, 0>, false>>,
  Expect<Equal<GreaterThan<20, 20>, false>>
]

我的解答

type GreaterThan<
  T extends number,
  U extends number,
  A extends any[] = []
> = T extends A["length"]
  ? false
  : U extends A["length"]
  ? true
  : GreaterThan<T, U, [...A, number]>;

知识点

  1. tuple length来管控长度
  2. 递归的方式来实现