type-challenges:Flip Arguments

15 阅读1分钟

Flip Arguments

实现 typesctipt版本的 lodash方法 _.flip

类型 FlipArguments <T> 要求函数类型 T,并返回一个新的函数类型,该函数类型具有相同的 T 返回类型,但参数是相反的。

举例:

type Flipped = FlipArguments<(arg0: string, arg1: number, arg2: boolean) => void> 
// (arg0: boolean, arg1: number, arg2: string) => void
// ============= Test Cases =============
import type { Equal, Expect } from './test-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 errors = [
  // @ts-expect-error
  FlipArguments<'string'>,
  // @ts-expect-error
  FlipArguments<{ key: 'value' }>,
  // @ts-expect-error
  FlipArguments<['apple', 'banana', 100, { a: 1 }]>,
  // @ts-expect-error
  FlipArguments<null | undefined>
]
​
// ============= Your Code Here =============
type Reverse<T extends any[]> = T extends [infer F, ...infer R] ? [...Reverse<R>, F] : T
type FlipArguments<T extends (...args: any[]) => any> = T extends (...args: infer R) => infer U
  ? (...args: Reverse<R>) => U
  : T
​

之前我们已经实现了 Reverse 类型,将元组中的类型颠倒顺序,这道题刚好可以用上,观察测试用例可以发现,传入的参数必须为函数类型,所以需要给泛型 T 添加约束 T extends (...args: any[]) => any,其次,只需要将函数的形参颠倒即可,使用 infer 关键字将所有形参类型传入其中,使用Reverse类型将其颠倒返回即可。