printf
Challenge
Implement Format<T extends string> generic.
For example,
type FormatCase1 = Format<"%sabc">; // FormatCase1 : string => string
type FormatCase2 = Format<"%s%dabc">; // FormatCase2 : string => number => string
type FormatCase3 = Format<"sdabc">; // FormatCase3 : string
type FormatCase4 = Format<"sd%abc">; // FormatCase4 : string
Solution
/*
Wandelt die Platzhalter wie %s oder %d in einen Array aus Typen um ([string, number])
z.B. `xxx%sxxx%d' : [string, number]
*/
type ArrayOfPlaceholders<
T extends string,
Acc extends any[] = []
> = T extends `${infer H}%${infer Char}${infer Rest}`
> ? Char extends "d" | "s"
? Char extends "d"
? ArrayOfPlaceholders<Rest, [...Acc, number]>
: ArrayOfPlaceholders<Rest, [...Acc, string]>
: ArrayOfPlaceholders<Rest, Acc>
: Acc;
/*
Nimmt eine Tupel entgegen und erzeugt eine Reihe von Funktionsaufrufen, die am Ende immer einen `string` zurueckgeben.
Eingabe: [string, number]
Ausgabe: (arg: string) => (arg:number) => string
*/
type ArrayToChainedCalls<T extends any[]> = T extends [infer H, ...infer Rest]
? (arg: H) => ArrayToChainedCalls<Rest>
: string;
type Format<T extends string> = ArrayToChainedCalls<ArrayOfPlaceholders<T>>;