Percentage Parser
Challenge
Implement PercentageParser/^(\+|\-)?(\d*)?(\%)?$/ regularity to match T and get three matches.
The structure should be: [plus or minus, number, unit]
If it is not captured, the default is an empty string.
For example:
type PString1 = "";
type PString2 = "+85%";
type PString3 = "-85%";
type PString4 = "85%";
type PString5 = "85";
type R1 = PercentageParser<PString1>; // expected ['', '', '']
type R2 = PercentageParser<PString2>; // expected ["+", "85", "%"]
type R3 = PercentageParser<PString3>; // expected ["-", "85", "%"]
type R4 = PercentageParser<PString4>; // expected ["", "85", "%"]
type R5 = PercentageParser<PString5>; // expected ["", "85", ""]
Solution
Zur Lösung dieser Herausforderung hilft es, ein paar Hilfstypen zu definieren, um den finalen Typ zu vereinfachen und lesbarer zu gestalten:
// Alle Zahlen als Vereinigung
type Numbers = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
// Alle Operatoren
type Operator = "-" | "+";
// Alle Einheiten
type Unit = "%";
Nun laufen wir einfach wieder über alle Zeichen der Zeichenkette und prüfen, ob das jeweilige Zeichen nun eine Nummer, ein Operator oder eine Unit ist. Je nach Falls speichern wir das Zeichen in den Akkumulatoren Pre (Anfang), N (Alphabetische Zeichenkette), Post (Ende).
type PercentageParser<
T extends string,
Pre extends string = "",
N extends string = "",
Post extends string = ""
> = T extends `${infer H}${infer T}`
? H extends Numbers
? PercentageParser<T, Pre, `${N}${H}`, Post>
: H extends Operator
? PercentageParser<T, `${H}`, N, Post>
: H extends Unit
? PercentageParser<T, Pre, N, `${H}`>
: never
: [Pre, N, Post];