Advanced TypeScript Exercises - Answer 4
Pragmatic Maciej
Posted on February 22, 2020
The question was about creating utility generic type which will be able to get any function type and create a new type which will have one argument more at the front.
Solution 1: Using Parameters and ReturnType utility types
type AppendArgument<F extends (...args: any) => any, A>
= (x: A, ...args: Parameters<F>) => ReturnType<F>
// using
type FinalF = AppendArgument<(a: number, b: string) => number, boolean>
// FinalF is (x: boolean, a: number, b: string) => number đź‘Ť
What we did here:
- first argument
F
is narrowed to only function types(...args: any) => any
, such narrowing is crucial in order to useParameters
andReturnType
- we create a type which first argument is type
A
and other arguments are spread by...
from the original function byParameters
which produce arguments types of the original type - we say that our new type returns the same thing as the original was by
ReturnType
Solution 2: Using infer
type AppendArgument<F, A>
= F extends (...args: infer Args) => infer Return
? (x: A, ...args: Args) => Return
: never
// using
type SomeF = (a: number, b: string) => number
type FinalF = AppendArgument<SomeF, boolean>
// FinalF is (x: boolean, a: number, b: string) => number
The second proposition isn't using any utility types, but we use directly infer
which is a tool for getting types from generic types, and function is this kind of a type, parameterized by two parameters - arguments type and return type.
Note we can understand utility types ReturnType and Parameters as types abstraction which are using
infer
in the definition, so they are kind of abstraction over construct we did in solution 2
What we did here:
- we infer all arguments by
...args: infer Args
and return type by=> infer Return
- we are putting newly obtained types in the definition, with putting as first argument type
A
exactly as we did in solution 1 - take a look that we needed to use conditional type, as this is the only way we can work with
infer
If you want to know more about infer
check the Answer 1 from the series
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 February 22, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 28, 2024