Reputation: 4343
type SomeFunc = (a:string, b:number, c:someCustomType) => number;
I want to create a type that is just like the one above, except there is a single parameter added at the end. Let's say, d:number
;
type SomeFuncAltered = (a:string, b:number, c:someCustomType, d:number) => number;
I do not want to craft the entire type manually though, I'm pretty sure there's a smart trick with Parameters<func>
to be used here.
Upvotes: 18
Views: 10954
Reputation: 261
As the accepted answer here doesn't seem to work for me (using TS 4), I wrote my own type that adds any number of parameters to the end of a function.
type AddParameters<
TFunction extends (...args: any) => any,
TParameters extends [...args: any]
> = (
...args: [...Parameters<TFunction>, ...TParameters]
) => ReturnType<TFunction>;
Usage:
type SomeFunc = (a: string, b: number, c: someCustomType) => number;
type SomeFuncAltered = AddParameters<SomeFunc, [d: number]>;
// SomeFuncAltered = (a:string, b:number, c:someCustomType, d:number) => number;
Note: This solution also allows you to add named parameters.
Upvotes: 21
Reputation: 20132
Its possible but quite sophisticated. More info can be found in this answer from @jcalz - Push type to the end of the tuple with skipping optional .
In your case we can reuse some utilities from above answer, exactly it would be Cons
and Push
and by using them make final type you need AddArgument
. Consider:
type SomeFunc = (a: string, b: number, c: string) => number;
// some utility types for working with tuples
type Cons<H, T extends readonly any[]> =
((head: H, ...tail: T) => void) extends ((...cons: infer R) => void) ? R : never;
type Push<T extends readonly any[], V>
= T extends any ? Cons<void, T> extends infer U ?
{ [K in keyof U]: K extends keyof T ? T[K] : V } : never : never;
// final type you need
type AddArgument<F, Arg> =
F extends ((...args: infer PrevArgs) => infer R)
? (...args: Push<PrevArgs, Arg>) => R : never
// function type with added boolean argument at the end
type NewFunction = AddArgument<SomeFunc, boolean>
Upvotes: 4
Reputation: 1533
You can use additional type for the base function args:
type FuncBaseArgs = {
a: string;
b: number;
c: boolean;
}
type SomeFunc = ({...obj }: FuncBaseArgs) => number;
type SomeFuncAltered = ({...obj }: FuncBaseArgs, d: number) => number;
Upvotes: 2