Eins oder viele: Array.isArray
Manche Funktionen sind handlicher, wenn sie einen Wert oder mehrere akzeptieren. Eine Truhe kann einen Gegenstand oder eine Liste von Gegenständen enthalten, und du möchtest dieselbe Funktion für beides aufrufen: oeffneTruhe("Silberschwert") ebenso wie oeffneTruhe(["Heiltrank", "Seil"]). Der Typ eines solchen Parameters ist string | string[]: ein Text oder ein Array von Texten.
Vergleiche ihn mit dem Array-Typ aus der Übung zu typeof: string | string[] ist „ein Text oder ein Array von Texten“, während (string | number)[] „ein Array, dessen Elemente Texte oder Zahlen sind“ ist. Die Klammern entscheiden, wozu das [] gehört.
Wie findest du heraus, was du bekommen hast? typeof kann ein Array nicht erkennen: Für ein Array liefert es "object", genau wie für jedes Objekt. (Hier würde typeof beute === "string" auch funktionieren, weil die einzige andere Möglichkeit ein Array ist.) JavaScript hat eine Funktion, die für Arrays gemacht ist: Array.isArray(wert) gibt true zurück, wenn der Wert ein Array ist, und sonst false. TypeScript versteht sie und grenzt den Typ ein:
function oeffneTruhe(beute: string | string[]): void {
if (Array.isArray(beute)) {
for (const gegenstand of beute) {
console.log(`Du findest: ${gegenstand}`);
}
} else {
console.log(`Du findest: ${beute}`);
}
}
oeffneTruhe(["Heiltrank", "Seil"]);
oeffneTruhe("Silberschwert");Das gibt aus:
Du findest: Heiltrank
Du findest: Seil
Du findest: SilberschwertInnerhalb des if ist beute ein string[], im else-Zweig ein string. Ohne die Prüfung erlaubt TypeScript nur, was für beide funktioniert, und Array-Methoden gehören nicht dazu:
function oeffneTruhe(beute: string | string[]): void {
beute.push("Seil");
}main.ts(2,11): error TS2339: Property 'push' does not exist on type 'string | string[]'.
Property 'push' does not exist on type 'string'.Aber Vorsicht: Manches funktioniert für beide Typen, und dann beschwert sich TypeScript nicht, auch wenn das Ergebnis nicht das ist, was du wolltest. Texte und Arrays haben beide length, und du kannst beide mit for...of durchgehen. Ohne die Prüfung würde oeffneTruhe("Seil") die Buchstaben des Textes durchgehen:
function oeffneTruhe(beute: string | string[]): void {
for (const gegenstand of beute) {
console.log(`Du findest: ${gegenstand}`);
}
}
oeffneTruhe("Seil");Das gibt aus:
Du findest: S
Du findest: e
Du findest: i
Du findest: lTypeScript prüft, dass das, was du tust, für die Typen erlaubt ist. Es kann nicht prüfen, dass es das ist, was du wolltest.
So schreibst du es:
Anweisungen
- 1
Das Programm gibt
3und13aus. TypeScript erlaubtbeute.length, weil auch Texte einelengthhaben, aber bei"Silberschwert"ist es die Anzahl der Zeichen. BehebezaehleGegenstaendemitArray.isArray, sodass ein einzelner Gegenstand als 1 zählt. Das Programm gibt dann aus:3 1 - 2
Schreibe darunter eine Funktion
zeigeBeutemit einem Parameterbeutevom Typstring | string[]. Sie gibt jeden Gegenstand in einer eigenen Zeile aus, mit-davor. - 3
Rufe
zeigeBeutefür dieselben zwei Truhen auf. Das Programm gibt dann aus:3 1 - Heiltrank - Alter Schlüssel - Seil - Silberschwert