Einschränkungen
Schreiben wir eine generische Funktion, die das Stärkste von allem findet, was eine kraft hat: Helden, Monster, Zauber.
function staerkstes<T>(dinge: T[]): T {
let bestes = dinge[0];
for (const ding of dinge) {
if (ding.kraft > bestes.kraft) {
bestes = ding;
}
}
return bestes;
}TypeScript meldet:
main.ts(4,18): error TS2339: Property 'kraft' does not exist on type 'T'.
main.ts(4,33): error TS2339: Property 'kraft' does not exist on type 'T'.TypeScript hat recht: T kann jeder Typ sein, also könnte staerkstes mit einem Array von Zahlen oder Texten aufgerufen werden, die keine kraft haben. Du musst sagen, welche Typen erlaubt sind. Das ist eine Einschränkung (englisch constraint):
type Held = { name: string; kraft: number };
type Monster = { art: string; kraft: number; beute: string };
function staerkstes<T extends { kraft: number }>(dinge: T[]): T {
let bestes = dinge[0];
for (const ding of dinge) {
if (ding.kraft > bestes.kraft) {
bestes = ding;
}
}
return bestes;
}
const helden: Held[] = [
{ name: "Kira", kraft: 7 },
{ name: "Bruno", kraft: 9 },
];
const monster: Monster[] = [
{ art: "Goblin", kraft: 3, beute: "Rostiger Dolch" },
{ art: "Troll", kraft: 8, beute: "Große Keule" },
];
console.log(staerkstes(helden).name);
console.log(staerkstes(monster).beute);Das gibt aus:
Bruno
Große KeuleT extends { kraft: number } bedeutet: T kann jeder Typ sein, der eine kraft hat, die eine Zahl ist (und außerdem alles andere). Es ist dasselbe Wort wie in interface Endgegner extends Monster aus der Lektion Objekttypen: „passt zu dieser Form und darf mehr haben“. In der Funktion ist ding.kraft jetzt erlaubt. Und das Ergebnis behält den vollen Typ: Für Helden gibt staerkstes einen Held zurück, also funktioniert .name; für Monster ein Monster mit seiner beute.
Aufrufe mit Arrays, die nicht zur Einschränkung passen, sind Fehler. Füge diese beiden Zeilen am Ende des Programms hinzu:
const namen = ["Kira", "Bruno"];
console.log(staerkstes(namen));TypeScript meldet:
main.ts(26,24): error TS2345: Argument of type 'string[]' is not assignable to parameter of type '{ kraft: number; }[]'.
Type 'string' is not assignable to type '{ kraft: number; }'.Warum nicht ohne Generics? Eine Funktion staerkstes(dinge: { kraft: number }[]): { kraft: number } akzeptiert dieselben Arrays, gibt aber nur ein { kraft: number } zurück. TypeScript vergisst, dass es ein Held war, und staerkstes(helden).name ergibt Property 'name' does not exist on type '{ kraft: number; }'. (TS2339). Mit einer Einschränkung bekommst du beides: Die Einschränkung sagt, was die Funktion braucht, und der Typparameter behält, was der Aufrufer hat.
Die Einschränkung kann jeder Typ sein, auch ein benannter: Mit type Stark = { kraft: number }; schreibst du <T extends Stark>.
So schreibst du es:
Anweisungen
- 1
Schreibe eine generische Funktion
findeNachName<T extends { name: string }>(dinge: T[], name: string): T | undefined. Sie gibt das erste Element zurück, dessen Eigenschaftnamegleich dem Parameternameist, oderundefined, wenn es keines gibt; verwendefind. - 2
Gib mit
findeNachNamedieheldenKlassevon Bruno aus, denpreisdes Silberschwerts und das, was für den Namen"Drachenei"im Laden gefunden wird. (Die Ergebnisse könnenundefinedsein, verwende also?..) Das Programm gibt aus:Krieger 120 undefined