DEV Community

Pragmatic Maciej
Pragmatic Maciej

Posted on • Updated on

Advanced TypeScript Exercises - Question 4

For given function type F, 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 F as first argument, A as second and will produce function type G which will be the same as F but with appended argument A as a first one.

// lets say we have some function type
type SomeF = (a: number, b: string) => number
// and we have our utility type
type AppendArgument<F, A> = ... here your code 💪

type FinalF = AppendArgument<SomeF, boolean> 
// FinalF should be (x: boolean, a: number, b: string) => number
Enter fullscreen mode Exit fullscreen mode

Post your answers in comments. Have fun! Answer will be published soon!

This series is just starting. If you want to know about new exciting questions from advanced TypeScript please follow me on dev.to and twitter.

Top comments (7)

Collapse
 
kashyaprahul94 profile image
Rahul Kashyap
// lets say we have some function type
type SomeF = (a: number, b: string) => number

// and we have our utility type
type AppendArgument<F extends (...args: any[]) => any, A> = (x: A, ...args: Parameters<F>) => ReturnType<F>

type FinalF = AppendArgument<SomeF, boolean> 
// FinalF should be (x: boolean, a: number, b: string) => number
Enter fullscreen mode Exit fullscreen mode

Playground Link

Collapse
 
muzichen profile image
ChenLee

You should keep the arguments' order, so x must after a and b.

Collapse
 
jasperdesutter profile image
Jasper De Sutter
// lets say we have some function type
type SomeF = (a: number, b: string) => number
// and we have our utility type
type AppendArgument<F, A> = F extends (...args: infer Args) => infer R ? (x: A, ...args: Args) => R : never

type FinalF = AppendArgument<SomeF, boolean> 
// FinalF should be (x: boolean, a: number, b: string) => number
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jrumandal profile image
John Ralph Umandal • Edited
// lets say we have some function type
type SomeF = (a: number, b: string) => number;
// and we have our utility type
type AppendArgument<F, A> =
    F extends (...[a, b, ...oth]: [infer ArgA, infer ArgB, infer ArgOth]) => infer FReturn
    ? (x: A, ...[a, b, ...oth]: [ArgA, ArgB, ArgOth]) => FReturn
    : unknown;

type FinalF = AppendArgument<SomeF, boolean> 
// FinalF should be (x: boolean, a: number, b: string) => number

I wasn't able to figure out myself how to dynamically take the pair arg:type out from a generic type function :(

UPDATE: palmface

// lets say we have some function type
type SomeF = (a: number, b: string) => number;
// and we have our utility type
type AppendArgument<F, A> =
    F extends (...args: infer Args) => infer FReturn
    ? (x: A, ...args: Args) => FReturn
    : unknown;

type FinalF = AppendArgument<SomeF, boolean> 
// FinalF should be (x: boolean, a: number, b: string) => number
Collapse
 
dwjohnston profile image
David Johnston • Edited

Just a note - the term 'append' means to 'add to the end of' (that's why the appendix is at the end of the book). The term you should be using here is `prepend'.

Collapse
 
macsikora profile image
Pragmatic Maciej

Yes agree.

Collapse
 
nmonastyrskyi profile image
Nikita Monastyrskiy • Edited

Interesting tasks, thanks!

To avoid spoilers - my answer in the TS Playground