[Typescript] 89. Hard - Currying 1

TypeScript 4.0 is recommended in this challenge

Currying is the technique of converting a function that takes multiple arguments into a sequence of functions that each take a single argument.

For example:

const add = (a: number, b: number) => a + b
const three = add(1, 2)

const curriedAdd = Currying(add)
const five = curriedAdd(2)(3)

The function passed to Currying may have multiple arguments, you need to correctly type it.

In this challenge, the curried function only accept one argument at a time. Once all the argument is assigned, it should return its result.

 

/* _____________ Your Code Here _____________ */

type Curried<F> = F extends (...args: infer Args) => infer RT
  ? Args extends [infer First, ...infer REST]             
    ? REST['length'] extends 0
      ? (a: First) => RT                                    
      : (a: First) => Curried<(...args: REST) => RT>     
    : () => RT
  : never;
declare function Currying<Fn>(fn: Fn): Curried<Fn>


/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'

const curried1 = Currying((a: string, b: number, c: boolean) => true)
const curried2 = Currying((a: string, b: number, c: boolean, d: boolean, e: boolean, f: string, g: boolean) => true)
const curried3 = Currying(() => true)

type cases = [
  Expect<Equal<
    typeof curried1, (a: string) => (b: number) => (c: boolean) => true
  >>,
  Expect<Equal<
    typeof curried2, (a: string) => (b: number) => (c: boolean) => (d: boolean) => (e: boolean) => (f: string) => (g: boolean) => true
  >>,
  Expect<Equal<typeof curried3, () => true>>,
]

 

posted @ 2022-11-08 02:57  Zhentiw  阅读(26)  评论(0编辑  收藏  举报