Aufwärmen · Aufgabe 1 von 7
// B2.4 · ca. 28 Min. · Einstieg
Typaliase und Interfaces im Vergleich
Nach dieser Lektion benennen Sie einen Typ einmal mit type oder interface, bauen einen Typ auf einem anderen auf und wählen begründet zwischen beiden.
Danach können Sie
- Einen Objekttyp mit einem Typalias oder einem Interface benennen und den Namen in Annotationen verwenden
- Einen Typ auf einem anderen aufbauen: ein Interface mit extends, einen Typalias mit &
- Den wichtigsten Unterschied, Declaration Merging, erklären und zwischen type und interface wählen
Vorhersagen · Aufgabe 2 von 7
Sagen Sie es vorher, bevor Sie weiterlesen: Eine Produkt-Id landet in einer Variablen für eine Nutzer-Id. Was meldet tsc?
type UserId = string; type ProductId = string; let current: UserId = "u-17"; const product: ProductId = "p-9"; current = product; console.log(current);Üben · Aufgabe 3 von 7
Setzen Sie das Schlüsselwort ein, mit dem Dog jede Eigenschaft von Animal bekommt, damit tsc rex akzeptiert und das Programm Rex the Collie ausgibt.
interface Animal { name: string; } interface Dog ____ Animal { breed: string; } const rex: Dog = { name: "Rex", breed: "Collie" }; console.log(rex.name + " the " + rex.breed);interface Dog Animal {Üben · Aufgabe 4 von 7
Person ist eine Intersection zweier Aliase. Was meldet tsc zuerst?
type Named = { name: string }; type Aged = { age: number }; type Person = Named & Aged; const ada: Person = { name: "Ada" };Üben · Aufgabe 5 von 7
Ordnen Sie jeder Deklaration zu, was sie tut.
Denksport · Aufgabe 6 von 7
Knobelaufgabe. Box ist zweimal deklariert, und box hat nur eine width. Was meldet tsc?
interface Box { width: number; } interface Box { height: number; } const box: Box = { width: 2 };Anwenden · Aufgabe 7 von 7
Kleine Aufgabe. Deklarieren Sie ein Interface Person mit name und optionaler email und ein Interface Employee, das Person um team erweitert. Schreiben Sie badge(employee: Employee), das Text wie Ada (Compilers) liefert, und rufen Sie es einmal auf. Schreiben Sie Employee danach als Typalias mit &, und prüfen Sie, dass tsc denselben Code weiterhin akzeptiert.
Prüfen Sie Ihr Ergebnis anhand dieser Liste
Selbst programmieren
Lesen Sie das ausgearbeitete Beispiel und lösen Sie dann die Übungen. Ihr Code läuft in Ihrem Browser oder auf Ihrem Computer und wird nie hochgeladen.
Ausgearbeitetes Beispiel
Benannte Typen für einen kleinen Katalog
Der Katalog enthält Bücher und Filme. ID ist ein Typalias, der eine Zahl oder einen String annimmt. Item ist ein Interface mit den Eigenschaften, die beide Arten teilen. Book erweitert Item mit extends; Film ist ein Typalias, der Item stattdessen mit & kombiniert. Jede Funktion nennt den Typ einmal in ihrer Signatur. Führen Sie npx tsc aus, dann node main.ts. Lassen Sie danach im letzten Aufruf pages weg, oder deklarieren Sie interface Item ein zweites Mal mit einer weiteren Eigenschaft, und lesen Sie, was tsc sagt.
main.ts
// Named types for a small library catalogue.
type ID = number | string;
interface Item {
id: ID;
title: string;
}
interface Book extends Item {
author: string;
pages: number;
}
type Film = Item & {
minutes: number;
};
function describeBook(book: Book): string {
return book.id + ": " + book.title + " by " + book.author + ", " + book.pages + " pages";
}
function describeFilm(film: Film): string {
return film.id + ": " + film.title + ", " + film.minutes + " min";
}
const dune: Book = { id: 1, title: "Dune", author: "Frank Herbert", pages: 412 };
const metropolis: Film = { id: "F-7", title: "Metropolis", minutes: 153 };
console.log(describeBook(dune));
console.log(describeFilm(metropolis));
console.log(describeBook({ id: 2, title: "Emma", author: "Jane Austen", pages: 474 }));
Ausführen mit
npx tsc
node main.tsAusgabe
1: Dune by Frank Herbert, 412 pages
F-7: Metropolis, 153 min
2: Emma by Jane Austen, 474 pages- dune hat eine Zahl als id, metropolis einen String: ID nimmt beides an.
- Book und Film bekommen id und title von Item, einmal über extends, einmal über &.
- Der letzte Aufruf übergibt ein Objektliteral direkt an describeBook; es wird wie jedes andere gegen Book geprüft.
- Die Namen gibt es nur für tsc: Node.js entfernt sie, und die Ausgabe ist die von einfachem JavaScript.
Ändern und ausführen
Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.
Beim ersten Ausführen lädt Ihr Browser den TypeScript-Compiler herunter (bis zu 2.1 MB) und speichert ihn im Cache. Ihr Code bleibt auf Ihrem Gerät.
Übungen
Übung 1 von 2
Den Typ benennen, den beide Funktionen verwenden
Beide Funktionen nehmen ein Product, aber tsc meldet Cannot find name 'Product'. Deklarieren Sie Product darüber, als Interface oder Typalias, mit name (string) und price (number). Ändern Sie nichts an den Funktionen. Starten Sie die Tests: Der erste ist die Typprüfung.
Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.
Beim ersten Ausführen lädt Ihr Browser den TypeScript-Compiler herunter (bis zu 2.1 MB) und speichert ihn im Cache. Ihr Code bleibt auf Ihrem Gerät.
Hinweise
Hinweis 1
Beide Meldungen sind gleich: Der Name Product wird verwendet, aber nie deklariert.
Hinweis 2
Ein Interface hat kein =: interface Product { … }. Ein Typalias hat eins: type Product = { … };
Hinweis 3
interface Product { name: string; price: number; } über der ersten Funktion genügt.
Eine Lösung zeigen
Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.
interface Product {
name: string;
price: number;
}
export function label(product: Product): string {
return product.name + ": " + product.price.toFixed(2) + " EUR";
}
export function isCheap(product: Product): boolean {
return product.price < 5;
}
Auf dem eigenen Computer ausführen
Installieren Sie TypeScript 7.0 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.
main.ts
export function label(product: Product): string {
return product.name + ": " + product.price.toFixed(2) + " EUR";
}
export function isCheap(product: Product): boolean {
return product.price < 5;
}
main.test.ts
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {label, isCheap} from './main.ts';
test('label zeigt Name und Preis', () => {
assert.equal(label({name: 'Pen', price: 1.5}), 'Pen: 1.50 EUR', 'label sollte Pen: 1.50 EUR liefern');
});
test('isCheap ist unter 5 true', () => {
assert.equal(isCheap({name: 'Pen', price: 1.5}), true, 'ein Preis von 1.5 sollte günstig sein');
});
test('isCheap ist ab 5 false', () => {
assert.equal(isCheap({name: 'Mug', price: 8}), false, 'ein Preis von 8 sollte nicht günstig sein');
});
package.json
{
"type": "module"
}
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "nodenext",
"lib": [
"esnext",
"dom"
],
"types": [],
"strict": true,
"noEmit": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true,
"allowImportingTsExtensions": true
},
"include": [
"**/*.ts"
],
"exclude": [
"**/*.test.ts"
]
}
npx tsc braucht TypeScript im Ordner: Führen Sie dort einmal npm install --save-dev typescript aus. tsc prüft die Typen; Node.js führt main.ts aus, indem es sie entfernt.
Programm ausführen:
npx tsc
node main.tsPrüfungen ausführen (learnrun.js muss im selben Ordner liegen):
npx tsc
node --testlearnrun.js herunterladenÜbung 2 von 2
Dog auf Animal aufbauen
describe liest name und legs aus einem Dog, aber Dog deklariert nur breed: tsc meldet Property 'name' does not exist on type 'Dog', und dasselbe für legs. Kopieren Sie die Eigenschaften nicht nach Dog. Lassen Sie Dog stattdessen auf Animal aufbauen, damit es jede Eigenschaft von Animal plus breed hat.
Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.
Beim ersten Ausführen lädt Ihr Browser den TypeScript-Compiler herunter (bis zu 2.1 MB) und speichert ihn im Cache. Ihr Code bleibt auf Ihrem Gerät.
Hinweise
Hinweis 1
Das JavaScript läuft: Nur die Typprüfung scheitert, weil Dog name und legs nicht kennt.
Hinweis 2
Ein Schlüsselwort nach interface Dog lässt es alle Member eines anderen Interfaces übernehmen.
Hinweis 3
Schreiben Sie interface Dog extends Animal {
Eine Lösung zeigen
Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.
interface Animal {
name: string;
legs: number;
}
interface Dog extends Animal {
breed: string;
}
export function describe(dog: Dog): string {
return dog.name + " the " + dog.breed + " has " + dog.legs + " legs";
}
Auf dem eigenen Computer ausführen
Installieren Sie TypeScript 7.0 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.
main.ts
interface Animal {
name: string;
legs: number;
}
interface Dog {
breed: string;
}
export function describe(dog: Dog): string {
return dog.name + " the " + dog.breed + " has " + dog.legs + " legs";
}
main.test.ts
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {describe} from './main.ts';
test('describe nennt den Hund, seine Rasse und seine Beine', () => {
assert.equal(describe({name: 'Rex', breed: 'Collie', legs: 4}), 'Rex the Collie has 4 legs', 'describe sollte Rex the Collie has 4 legs liefern');
});
test('describe funktioniert auch für einen anderen Hund', () => {
assert.equal(describe({name: 'Tripod', breed: 'Beagle', legs: 3}), 'Tripod the Beagle has 3 legs', 'describe sollte Tripod the Beagle has 3 legs liefern');
});
package.json
{
"type": "module"
}
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "nodenext",
"lib": [
"esnext",
"dom"
],
"types": [],
"strict": true,
"noEmit": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true,
"allowImportingTsExtensions": true
},
"include": [
"**/*.ts"
],
"exclude": [
"**/*.test.ts"
]
}
npx tsc braucht TypeScript im Ordner: Führen Sie dort einmal npm install --save-dev typescript aus. tsc prüft die Typen; Node.js führt main.ts aus, indem es sie entfernt.
Programm ausführen:
npx tsc
node main.tsPrüfungen ausführen (learnrun.js muss im selben Ordner liegen):
npx tsc
node --testlearnrun.js herunterladenHäufige Fehler
Ein = nach interface
interface Point = {
x: number;
y: number;
};
Was tsc oder Node.js ausgibt
main.ts(1,17): error TS1005: '{' expected.Warum, und die Lösung
type und interface werden unterschiedlich geschrieben. Ein Typalias braucht =: type Point = { x: number; y: number };. Ein Interface hat kein =, die geschweiften Klammern folgen dem Namen: interface Point { x: number; y: number }. Die Meldung '{' expected zeigt auf das =, Spalte 17, wo tsc die Klammer erwartet hat.
Derselbe Typalias zweimal deklariert
type Settings = { theme: string };
type Settings = { fontSize: number };
Was tsc oder Node.js ausgibt
main.ts(1,6): error TS2300: Duplicate identifier 'Settings'.Warum, und die Lösung
Ein Typalias lässt sich nicht wieder öffnen, also meldet tsc beide Deklarationen (Zeile 1 und 2). Fassen Sie alle Eigenschaften in einer zusammen: type Settings = { theme: string; fontSize: number };. Zwei Deklarationen interface Settings würden stattdessen verschmelzen, was erlaubt ist, aber eine zweite Deklaration weit weg in der Datei übersieht man leicht; behalten Sie eine.
Eine Eigenschaft des Basis-Interfaces vergessen
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
const rex: Dog = { breed: "Collie" };
Was tsc oder Node.js ausgibt
main.ts(9,7): error TS2741: Property 'name' is missing in type '{ breed: string; }' but required in type 'Dog'.Warum, und die Lösung
Dog erweitert Animal, also braucht ein Dog jede Eigenschaft von Animal und dazu seine eigenen. Die Meldung nennt die fehlende, name, und den Typ, der sie verlangt, Dog. Ergänzen Sie sie: { name: "Rex", breed: "Collie" }.
TypeScript im Browser: der Compiler von TypeScript 6.0.3, Apache-2.0, danach die eigene Engine Ihres Browsers. Lizenz und Quellcode
Abschlussquiz
5 Fragen, ohne Hinweise. Ab 80 % ist die Lektion abgeschlossen.
Erledigen Sie zuerst alle Aufgaben oben, um das Abschlussquiz freizuschalten.