이 글은 제가 타입챌린지를 하면서 해석한 내용을 적는 글입니다. 틀린 내용이 있으면 댓글 달아주시면 감사하겠습니다.
함수의 인자를 뒤집어서 리턴하는 타입이다.
예를들면
function (a: string, b: number, c: boolean) 을 function (a: boolean, b:number, c: string) 으로 말이다.
이때까지 함수에 대해 타입을 많이 구현해보지 않아서 조금 헤맸지만, 그래도 할만하다.
type Push<T, U> = T extends any[] ? [...T, U] : never;
type FlipArguments<T extends (...args:any) => any, U extends any[] = []> =
T extends (...args: infer F) => infer R ?
F extends [...infer O, infer L] ?
FlipArguments<(...args: O) => R, Push<U, L>> : (...args: U) => R : never;
/* _____________ Test Cases _____________ */
import type { Equal, Expect } 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 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>,
]
일단, Push 타입을 만들어 배열 맨 뒤에 인자를 Push가능하게 해주었다.
type FlipArguments<T extends (...args:any) => any, U extends any[] = []> : FlipArguments라는 타입을 정의하고, T는 여러 인자를 가진 함수라고 정의한다. 그리고 U는 빈 배열을 기본 값으로 가진다.
T extends (...args: infer F) => infer R ? : T가 F를 타입으로 갖는 인자들을 가지고, 리턴 타입이 R일 때,
F extends [...infer O, infer L] ? : F에서 마지막 인자인 L를 뽑아서
FlipArguments<(...args: O) => R, Push<U, L>> : 재귀를 하는데, 재귀시 T의 위치에는 나머지 인자 O를 가지고 리턴값이 R인 함수가 들어가고, U의 위치에는 원래 U에 L를 push한 배열이 들어간다.
(...args: U) => R : never : 그리고 재귀가 끝나면 T에서 인자가 뒤집인 배열인 U를 인자로하고 리턴값이 R인 함수를 반환한다.
'Language > Typescript' 카테고리의 다른 글
타입챌린지 : 3326-BEM style string (medium) (0) | 2023.09.14 |
---|---|
타입챌린지 : 3243-FlattenDepth (medium) (0) | 2023.05.30 |
타입챌린지 : 3192-Reverse (medium) (0) | 2023.05.25 |
타입챌린지 : 3188-Tuple to Nested Object (medium) (0) | 2023.05.23 |
타입챌린지 : 3062-Shift (medium) (0) | 2023.05.22 |