Append Argument
Challenge
For given function type Fn, 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 Fn as the first argument, A as the second, and will produce function type G which will be the same as Fn but with appended argument A as a last one.
For example,
type Fn = (a: number, b: string) => number;
type Result = AppendArgument<Fn, boolean>;
// expected be (a: number, b: string, x: boolean) => number
This question is ported from the original article by @maciejsikora
Solution
Zur Lösung dieses Problems können wir wieder über einen konditionellen Typen die Argumente sowie den Rückgabetyp der Funktion inferen. Da der Typ nur eine Funktion entgegennimmt, können wir die Argumente des Typen mit dieser Bedingung versehen:
type AppendArgument<Fn extends (...args: any[]) => void, A>
Wie bereits gesehen, werden die Funktionsargumente als ein Array geführt. Entsprechend können wir uns einfach die bestehenden Argumente als Array holen (infer U), und einfach diese mittels Spread-Operator in einem neuen Array mit dem zweiten Typ-Argument U zusammenführen:
type AppendArgument<Fn extends (...args: any[]) => void, A> = Fn extends (
...args: infer U
) => infer R
? (...args: [...U, A]) => R
: never;