Parameters And Return Type
Problem - Parameters On Github - Return On Github
This time the challenge is to create a copy of the inbuilt Parameters
and ReturnType
utility types that are provided in Typescript. Thes types accept a function as their generic and return different types based on it.
The Parameters type gives an array of the parameter types that the given function provides. For instance, (one: string, two: boolean) => any
will give [string, boolean]
as a result.
The ReturnType type gives the return type of the function. For instance, () => boolean
will give boolean
as a result.
The initial types provided are:
type MyParameters<T extends (...args: any[]) => any> = any
type MyReturnType<T> = any
Solution for Parameters
The given type in this situation is a bit more detailed than the previous questions. The generic type T
has been explicitly set to have the shape (...args: any[]) => any
which we can use to out advantage. We know that our return type will need to be the actual types from the any[]
part.
Below the extends condition has been copied across and added to a ternary where the any[]
value passed back.
type MyParameters<T extends (...args: any[]) => any>
// if the signature is the same, we should change `any[]`
= T extends (...args: any[]) => any ? any[] : never;
// the Result type equals `any[]`
type Result = MyParameters<(a: string, b: number) => void>;
This is most of the way there. Now what we need to do if figure out the actual type that the any[]
is. This is done in Typescript using the infer
keyword. Creating a new Generic type with infer lets Typescript know to pass through the type information of the given parameter.
type MyParameters<T extends (...args: any[]) => any>
// now infering the `any[]` type
= T extends (...args: infer U) => any ? U : never;
// the Result type equals `[string, number]`
type Result = MyParameters<(a: string, b: number) => void>;
Converting to the Returns type
The return type is almost identical to the parameters type - it is only the infer that needs to change its location. Moving infer U
to be on the return of the given function rather than the parameters will do what we want.
type MyReturnType<T extends (...args: any[]) => any>
// now infering the return type
= T extends (...args: any[]) => infer U ? U : never;
// the Result type equals `boolean`
type Result = MyReturnType<(a: string, b: number) => boolean>;
What to read more? Check out more posts below!