Includes
Challenge
Implement the JavaScript Array.includes function in the type system. A type takes the two arguments. The output should be a boolean true or false.
For example:
type isPillarMen = Includes<["Kars", "Esidisi", "Wamuu", "Santana"], "Dio">; // expected to be `false`
Solution
Eine einfachere Lösung ist es, auch hier einen Lookup-Typ zu nutzen. Hier ist das bereits vordefinierte readonly [] auf dem Eingabetyp angegeben. Nutzt man den Lookup-Typ number, dann erhält man eine Vereinigung der Elemente aus dem Array (nur bei readonly Arrays, und damit Tupeln möglich).
(["Kars", "Esidisi", "Wamuu", "Santana"] as readonly [])[number]; // Kars | Esidisi | Wamuu ....
Nun ist es möglich, jeden Wert des Arrays mit dem übergebenen Typ zu vergleichen, da Vereinigungen in konditionellen Typen distributiv sind.
// Beispiel: T = ["Kars", "Esidisi"] U = "Dio"
// "Kars" extends "Dio" ? true : false
// "Esidisi" extends "Dio" ? true : false
type Includes<T extends readonly [], U> = T[number] extends U ? true : false;
Alternativ kann man auch wieder einen konditionellen Typen infer nutzen, um nacheinander ein Element nach dem anderen aus dem Array zu extrahieren und auf die Gleichheit mit U zu prüfen:
type Includes<T extends readonly any[], U> = T extends [
infer First,
...infer Last
]
? Equal<First, U> extends true
? true
: Includes<Last, U>
: false;