loading...

Advanced TypeScript Exercises - Question 4

macsikora profile image Maciej Sikora Updated on ・1 min read

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

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.

Posted on by:

macsikora profile

Maciej Sikora

@macsikora

I am Software Developer, currently interested in static type languages (TypeScript, Elm, Reason) mostly in the frontend land. I am available for mentoring, I can help with type systems and FP.

Discussion

markdown guide
 
// 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

Playground Link

 
// 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
 
// 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
 

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'.