|
| 1 | +/* |
| 2 | + 191 - Append Argument |
| 3 | + ------- |
| 4 | + by Maciej Sikora (@maciejsikora) #medium #arguments |
| 5 | +
|
| 6 | + ### Question |
| 7 | +
|
| 8 | + For given function type `Fn`, and any type `A` (any in this context means we don't restrict the type, and I don't have in mind any type 😉) create a generic type which will take `Fn` as the first argument, `A` as the second, and will produce function type `G` which will be the same as `Fn` but with appended argument `A` as a last one. |
| 9 | +
|
| 10 | + For example, |
| 11 | +
|
| 12 | + ```typescript |
| 13 | + type Fn = (a: number, b: string) => number |
| 14 | +
|
| 15 | + type Result = AppendArgument<Fn, boolean> |
| 16 | + // expected be (a: number, b: string, x: boolean) => number |
| 17 | + ``` |
| 18 | + > This question is ported from the [original article](https://dev.to/macsikora/advanced-typescript-exercises-question-4-495c) by [@maciejsikora](https://github.com/maciejsikora) |
| 19 | +
|
| 20 | + > View on GitHub: https://tsch.js.org/191 |
| 21 | +*/ |
| 22 | + |
| 23 | +/* _____________ Your Code Here _____________ */ |
| 24 | +// my try |
| 25 | +type AppendArgument<Fn extends (...args: any[]) => unknown, A> = Fn extends ( |
| 26 | + ...args: infer P extends any[] |
| 27 | +) => any |
| 28 | + ? (...args: [...P, A]) => ReturnType<Fn> |
| 29 | + : never; |
| 30 | + |
| 31 | + // official answer |
| 32 | +type AppendArgument2<Fn extends (...args: any[]) => unknown, A> = ( |
| 33 | + ...args: [...Parameters<Fn>, A] |
| 34 | +) => ReturnType<Fn>; |
| 35 | + |
| 36 | +type Fn = (a: number, b: string) => number; |
| 37 | + |
| 38 | +type Result = AppendArgument<Fn, boolean>; |
| 39 | +// ^? |
| 40 | + |
| 41 | +/* _____________ Test Cases _____________ */ |
| 42 | +import type { Equal, Expect } from "@type-challenges/utils"; |
| 43 | + |
| 44 | +type Case1 = AppendArgument<(a: number, b: string) => number, boolean>; |
| 45 | +type Result1 = (a: number, b: string, x: boolean) => number; |
| 46 | + |
| 47 | +type Case2 = AppendArgument<() => void, undefined>; |
| 48 | +type Result2 = (x: undefined) => void; |
| 49 | + |
| 50 | +type cases = [ |
| 51 | + Expect<Equal<Case1, Result1>>, |
| 52 | + Expect<Equal<Case2, Result2>>, |
| 53 | + // @ts-expect-error |
| 54 | + AppendArgument<unknown, undefined> |
| 55 | +]; |
| 56 | + |
| 57 | +/* _____________ Further Steps _____________ */ |
| 58 | +/* |
| 59 | + > Share your solutions: https://tsch.js.org/191/answer |
| 60 | + > View solutions: https://tsch.js.org/191/solutions |
| 61 | + > More Challenges: https://tsch.js.org |
| 62 | +*/ |
0 commit comments