커링은 다양한 인자를 갖는 함수를 하나의 인자를 갖는 함수의 나열로 바꾸는 기술을 의미한다
Currying으로 넘어가는 함수는 다양한 인자를 가질 수 있고, 당신은 올바르게 타이핑 해야한다.
이 챌린지에서, 커링된 함수는 오직 한 번에 하나의 인자를 받는다. 모든 인자가 할단되면, 그것의 결과값을 반환해야 한다.
Currying is the technique of converting a function that takes multiple arguments into a sequence of functions that each take a single argument.
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.
type Curried<T extends Function>=
T extends (...args:infer Args)=>infer Result?
Args extends [infer FirstArg,...infer RestArg]?
RestArg['length'] extends 0?
(...args:[FirstArg])=>Result
:(...args:[FirstArg])=>Curried<(...args:RestArg)=>Result>
:()=>Result
:never
declare function Currying<Fn extends Function>(fn: Fn): Curried<Fn>
우선 리턴 타입에 해당되는 타입을 만들었다.
이후 함수 사용처에서 인자에 할당하는 제네릭을 만들고,
그 제네릭을 함수의 리턴타입에 적용시켜 반환했다.
반환되는 타입은 일반적인 재귀 함수와 비슷했다.
받은 함수에 infer를 통해 인자와 반환 값에 대한 타입을 추론한 후,
인자의 갯수가 0개면 바로 ()=>결과 타입을 반환한다.
인자의 갯수가 1개면 (인자)=>결과 타입을 반환한다.
인자의 갯수가 2개 이상이면 (첫번째 인자)=>재귀<(...두 번째 이후 인자)=>결과값>을 반환한다.
함수의 인자의 타입은 배열로 처리될 수 있다
예를 들어 (a:number,b:string)=>void와 같은 함수의 인자는
(...args:[a:number,b:string])=>void과 같다.
이때, [a:number,b:string]에서 a와 b는 각각 해당 요소가 함수의 인자로 들어갔을 때, 해당되는 이름이다. 함수의 인자로써 사용될 때를 제외하면 [number,string]과 같다고 봐도 무방하다.