Das Inventar
Jetzt Kiras Rucksack. Sie trägt drei Arten von Gegenständen bei sich: Tränke, die heilen, Waffen, die Schaden machen, und Schlüssel, die etwas öffnen. Jede Art hat andere Daten, also ist das Inventar ein Fall für eine diskriminierte Union aus der Lektion „Daten modellieren“. Jede Art ist ein eigener Objekttyp mit einem art-Tag, und Gegenstand ist die Union davon. Gib jeder Art einen eigenen Namen, Trank, Waffe und Schluessel: Im nächsten Schritt brauchst du den Typ Waffe allein.
Um einen Gegenstand zu beschreiben, verwende ein switch auf dem Tag. In jedem case weiß TypeScript, welche Art von Gegenstand es ist, also kannst du in case "trank" gegenstand.heilung verwenden. Und in den default-Zweig kommt die Vollständigkeitsprüfung mit never aus der Lektion „Daten modellieren“: Wenn irgendwann eine neue Art hinzukommt und ihr case vergessen wird, meldet TypeScript es genau dort. Zum Beispiel bei Zaubern:
type FeuerZauber = { art: "feuer"; name: string; schaden: number };
type EisZauber = { art: "eis"; name: string; runden: number };
type Zauber = FeuerZauber | EisZauber;
function beschreibeZauber(zauber: Zauber): string {
switch (zauber.art) {
case "feuer":
return `${zauber.name} verursacht ${zauber.schaden} Schaden`;
case "eis":
return `${zauber.name} friert für ${zauber.runden} Runden ein`;
default:
const unbehandelt: never = zauber;
return unbehandelt;
}
}
const zauber: Zauber[] = [
{ art: "feuer", name: "Feuerball", schaden: 30 },
{ art: "eis", name: "Frostnova", runden: 2 },
];
for (const einZauber of zauber) {
console.log(`- ${beschreibeZauber(einZauber)}`);
}Das gibt aus:
- Feuerball verursacht 30 Schaden
- Frostnova friert für 2 Runden einKiras Gegenstände kommen in eine neue Eigenschaft von Held, inventar: Gegenstand[]. In kira ist das ein Array von Objekten, und TypeScript prüft jedes davon gegen seine Art: Ein Trank mit schaden statt heilung wäre ein Fehler. Das Hauptprogramm gibt dann die Überschrift Inventar: aus und geht die Gegenstände mit for...of durch.
Typische Fehler:
- Ein Großbuchstabe in einem
case,case "Trank":. Das Tag ist genau der Text"trank", deshalb meldet TypeScriptType '"Trank"' is not comparable to type '"schluessel" | "trank" | "waffe"'., und dadurch noch ein paar weitere Fehler weiter unten. - Ein vergessener Fall. Ohne
case "schluessel"landet der Schlüssel indefault, und dienever-Prüfung nennt ihn:main.ts(36,19): error TS2322: Type 'Schluessel' is not assignable to type 'never'.
So schreibst du es:
Anweisungen
- 1
Schreibe unter
HeldenKlassedie TypenTrank(art: "trank", einnameundheilung, eine Zahl),Waffe(art: "waffe", einnameundschaden, eine Zahl) undSchluessel(art: "schluessel", einnameundoeffnet, ein Text) sowietype Gegenstand = Trank | Waffe | Schluessel;. Fügeinventar: Gegenstand[]zuHeldhinzu und gib Kira drei Gegenstände:{ art: "trank", name: "Heiltrank", heilung: 20 },{ art: "waffe", name: "Silberschwert", schaden: 12 }und{ art: "schluessel", name: "Alter Schlüssel", oeffnet: "die Gruft" }. - 2
Schreibe unter
beschreibeHeldeine FunktionbeschreibeGegenstand(gegenstand: Gegenstand): stringmit einemswitchaufgegenstand.artund dernever-Prüfung indefault. Für den Trank gibt sieHeiltrank (heilt 20)zurück, für die WaffeSilberschwert (Schaden 12)und für den SchlüsselAlter Schlüssel (öffnet die Gruft). - 3
Gib im Hauptprogramm unter der Zeile über Kira
Inventar:aus und danach jeden Gegenstand mit-davor, in einerfor...of-Schleife:Kira (Waldläufer), Stufe 3, Leben 34/50, Gold 120 Inventar: - Heiltrank (heilt 20) - Silberschwert (Schaden 12) - Alter Schlüssel (öffnet die Gruft)