类型体操刷题系列(十九)— Reverse/FilpArguements/FlattenDepth

271 阅读1分钟

目的

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

题目大纲

  1. Medium Reverse
  2. Medium Filp Arguements
  3. Medium Flatten Depth

01. Medium Reverse

题目要求

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

type cases = [
  Expect<Equal<Reverse<['a', 'b']>, ['b', 'a']>>,
  Expect<Equal<Reverse<['a', 'b', 'c']>, ['c', 'b', 'a']>>
]

我的答案

type Reverse<T extends any[]> = T extends [infer P, ...infer K]
  ? [...Reverse<K>, P]
  : [];

2. Medium Filp Arguements

题目要求

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

type cases = [
  Expect<Equal<FlipArguments<() => boolean>, () => boolean>>,
  Expect<Equal<FlipArguments<(foo: string) => number>, (foo: string) => number>>,
  Expect<Equal<FlipArguments<(arg0: string, arg1: number, arg2: boolean) => void>, (arg0: boolean, arg1: number, arg2: string) => void>>
]

我的解答

type FlipArguments<T> = T extends (...args: infer P) => infer R
  ? (...args: Reverse<P>) => R
  : never;

知识点

  1. 函数类型的推断
  2. 函数参数的参数用数组加上...运算符,可以转换为,分割的参数

3. Medium Flatten Depth

题目要求

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

type cases = [
  Expect<Equal<FlattenDepth<[]>, []>>,
  Expect<Equal<FlattenDepth<[1, 2, 3, 4]>, [1, 2, 3, 4]>>,
  Expect<Equal<FlattenDepth<[1, [2]]>, [1, 2]>>,
  Expect<Equal<FlattenDepth<[1, 2, [3, 4], [[[5]]]], 2>, [1, 2, 3, 4, [5]]>>,
  Expect<Equal<FlattenDepth<[1, 2, [3, 4], [[[5]]]]>, [1, 2, 3, 4, [[5]]]>>,
  Expect<Equal<FlattenDepth<[1, [2, [3, [4, [5]]]]], 3>, [1, 2, 3, 4, [5]]>>,
  Expect<Equal<FlattenDepth<[1, [2, [3, [4, [5]]]]], 19260817>, [1, 2, 3, 4, 5]>>,
]

我的解答

type FlattenDepth<
  T extends any[],
  N = 1,
  R extends any[] = [],
  C extends any[] = []
> = T extends [infer P, ...infer K]
  ? C["length"] extends N
    ? [...R, ...T]
    : P extends any[]
    ? FlattenDepth<K, N, [...R, ...FlattenDepth<P, N, [], [...C, number]>], C>
    : FlattenDepth<K, N, [...R, P], C>
  : R;

知识点

  1. 用数组的length来进行记数
  2. 使用默认值来实现参数递归过程中叠加