Appearance
Kapitel 3: Fortgeschrittene Typen
🎯 Lernziele
In diesem Kapitel lernen Sie:
- ✅ Union Types (
|) - ✅ Intersection Types (
&) - ✅ Type Aliases (
type) - ✅ Literal Types
- ✅ Optional Properties (
?) - ✅ Non-Null Assertion (
!) - ✅ Unknown Type
- ✅ Type Guards (
typeof,instanceof)
3.1 Union Types (|)
📖 Einfache Definition
Ein Union Type erlaubt einer Variable, mehrere Typen anzunehmen.
💻 Code-Beispiel
typescript
// Union Type
let value: string | number;
value = "Hallo"; // ✅ Erlaubt
value = 123; // ✅ Erlaubt
value = true; // ❌ Fehler: boolean ist nicht erlaubt
// Funktion mit Union Type
function formatId(id: string | number): string {
return `ID: ${id}`;
}
console.log(formatId("abc")); // Ausgabe: ID: abc
console.log(formatId(123)); // Ausgabe: ID: 123🎨 Praxis-Beispiel
typescript
// Array mit gemischten Typen
let mixedArray: (string | number)[] = ["Hallo", 1, "Welt", 2];
// Typen einschränken
function processValue(value: string | number): void {
if (typeof value === "string") {
console.log(value.toUpperCase()); // TS weiß: value ist string
} else {
console.log(value.toFixed(2)); // TS weiß: value ist number
}
}3.2 Intersection Types (&)
📖 Einfache Definition
Ein Intersection Type kombiniert mehrere Typen zu einem einzigen Typ, der alle Eigenschaften der kombinierten Typen hat.
💻 Code-Beispiel
typescript
// Zwei Interfaces
interface Person {
name: string;
age: number;
}
interface Employee {
employeeId: number;
department: string;
}
// Intersection Type
type EmployeePerson = Person & Employee;
// Verwendung
const emp: EmployeePerson = {
name: "Max",
age: 25,
employeeId: 12345,
department: "IT"
};🆚 Union vs Intersection
| Feature | Union (|) | Intersection (&) | |---------|-------------|-------------------| | Bedeutung | ODER (einer von beiden) | UND (beide kombiniert) | | Beispiel | string \| number | Person & Employee | | Werte | Eine von mehreren Typen | Alle Typen gleichzeitig |
3.3 Type Aliases (type)
📖 Einfache Definition
Ein Type Alias erstellt einen neuen Namen für einen Typ.
💻 Code-Beispiel
typescript
// Einfacher Type Alias
type StringOrNumber = string | number;
let value: StringOrNumber;
value = "Hallo"; // ✅
value = 123; // ✅
// Type Alias für Objekt
type User = {
id: number;
name: string;
email: string;
};
const user: User = {
id: 1,
name: "Max",
email: "max@example.com"
};
// Type Alias für Funktion
type GreetFunction = (name: string) => string;
const greet: GreetFunction = (name) => `Hallo, ${name}!`;💡 Vorteile von Type Aliases
typescript
// ✅ Wiederverwendbarkeit
type ID = string | number;
function getUserById(id: ID) { /* ... */ }
function deleteUserById(id: ID) { /* ... */ }
// ✅ Lesbarkeit
type UserRole = "admin" | "user" | "guest";
// ✅ Komplexe Typen vereinfachen
type ApiResponse<T> = {
success: boolean;
data: T;
message?: string;
};3.4 Literal Types
📖 Einfache Definition
Literal Types erlauben nur spezifische Werte, nicht alle Werte eines Typs.
💻 Code-Beispiel
typescript
// String Literal Type
type Direction = "north" | "south" | "east" | "west";
let dir: Direction;
dir = "north"; // ✅ Erlaubt
dir = "south"; // ✅ Erlaubt
dir = "up"; // ❌ Fehler
// Number Literal Type
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;
let roll: DiceRoll;
roll = 3; // ✅ Erlaubt
roll = 7; // ❌ Fehler
// Boolean Literal Type
type TrueOnly = true;
let isActive: TrueOnly = true; // ✅ Erlaubt
isActive = false; // ❌ Fehler🎨 Praxis-Beispiel
typescript
// Status einer API-Anfrage
type ApiStatus = "idle" | "loading" | "success" | "error";
function handleApiStatus(status: ApiStatus): void {
switch (status) {
case "idle":
console.log("Bereit");
break;
case "loading":
console.log("Lädt...");
break;
case "success":
console.log("Erfolgreich!");
break;
case "error":
console.log("Fehler aufgetreten");
break;
}
}3.5 Optional Properties (?)
📖 Einfache Definition
Optionale Eigenschaften müssen nicht zwingend vorhanden sein.
💻 Code-Beispiel
typescript
// Interface mit optionalen Eigenschaften
interface User {
id: number;
name: string;
email?: string; // Optional
age?: number; // Optional
}
// Erlaubt
const user1: User = {
id: 1,
name: "Max"
};
// Auch erlaubt
const user2: User = {
id: 2,
name: "Maria",
email: "maria@example.com",
age: 30
};⚠️ Zugriff auf optionale Eigenschaften
typescript
interface User {
name: string;
age?: number;
}
function printAge(user: User): void {
// ❌ Falsch: age könnte undefined sein
console.log(user.age.toFixed(2)); // Fehler!
// ✅ Richtig: Prüfen, ob age existiert
if (user.age !== undefined) {
console.log(user.age.toFixed(2));
}
// ✅ Richtig: Optional Chaining
console.log(user.age?.toFixed(2));
}3.6 Non-Null Assertion (!)
📖 Einfache Definition
Der Non-Null Assertion Operator (!) teilt dem Compiler, dass ein Wert nicht null oder undefined ist.
💻 Code-Beispiel
typescript
// Ohne Non-Null Assertion
function getElement(id: string): HTMLElement | null {
return document.getElementById(id);
}
const el1 = getElement("myDiv");
// ❌ Fehler: el1 könnte null sein
el1.innerHTML = "Hallo";
// ✅ Mit Non-Null Assertion (Vorsicht!)
const el2 = getElement("myDiv")!;
el2.innerHTML = "Hallo"; // OK (aber gefährlich!)⚠️ Warnung
typescript
// ❌ Gefährlich: Non-Null Assertion missbrauchen
function getValue(): string | undefined {
return undefined;
}
const value = getValue()!; // Erzwingt Typumwandlung
console.log(value.length); // Laufzeitfehler: Cannot read property 'length' of undefined
// ✅ Sicherer: Type Guard verwenden
const value2 = getValue();
if (value2 !== undefined) {
console.log(value2.length); // Sicher!
}3.7 Unknown Type (Sichere Alternative zu any)
📖 Einfache Definition
unknown ist wie any, aber typsicherer. Sie können nicht direkt Operationen auf einem unknown Wert ausführen.
💻 Code-Beispiel
typescript
// Any (Unsicher)
let anyValue: any = "Hallo";
anyValue.foo.bar(); // Keine Fehlermeldung zur Kompilierungszeit!
// Unknown (Sicherer)
let unknownValue: unknown = "Hallo";
unknownValue.foo.bar(); // ❌ Fehler: Object is of type 'unknown'
// ✅ Unknown muss zuerst überprüft werden
if (typeof unknownValue === "string") {
console.log(unknownValue.toUpperCase()); // OK
}🆚 Any vs Unknown
| Feature | any | unknown |
|---|---|---|
| Typsicherheit | Keine | Vollständig |
| Direkter Zugriff | Erlaubt | Verboten |
| Type Guards erforderlich | Nein | Ja |
| Empfehlung | Vermeiden | Verwenden statt any |
3.8 Type Guards
📖 Einfache Definition
Type Guards sind Techniken, um den Typ einer Variable zur Laufzeit einzuschränken.
💻 Code-Beispiel
typeof Type Guard
typescript
function processValue(value: string | number): void {
if (typeof value === "string") {
// value ist hier string
console.log(value.toUpperCase());
} else {
// value ist hier number
console.log(value.toFixed(2));
}
}instanceof Type Guard
typescript
class Car {
drive() {
console.log("Fährt...");
}
}
class Boat {
sail() {
console.log("Segelt...");
}
}
function useVehicle(vehicle: Car | Boat): void {
if (vehicle instanceof Car) {
vehicle.drive(); // TS weiß: vehicle ist Car
} else {
vehicle.sail(); // TS weiß: vehicle ist Boat
}
}Custom Type Guard (is)
typescript
interface Fish {
swim(): void;
}
interface Bird {
fly(): void;
}
// Custom Type Guard
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
function move(pet: Fish | Bird): void {
if (isFish(pet)) {
pet.swim(); // TS weiß: pet ist Fish
} else {
pet.fly(); // TS weiß: pet ist Bird
}
}📝 Zusammenfassung
In diesem Kapitel haben Sie gelernt:
- ✅ Union Types (
|): Variable kann mehrere Typen annehmen - ✅ Intersection Types (
&): Kombiniert mehrere Typen - ✅ Type Aliases (
type): Erstellt neue Namen für Typen - ✅ Literal Types: Erlaubt nur spezifische Werte
- ✅ Optional Properties (
?): Eigenschaften sind nicht zwingend erforderlich - ✅ Non-Null Assertion (
!): Erzwingt, dass Wert nicht null/undefined ist (Vorsicht!) - ✅ Unknown Type: Sicherere Alternative zu
any - ✅ Type Guards: Schränkt Typen zur Laufzeit ein
🎯 Nächstes Kapitel
Im Kapitel 4 lernen wir Interfaces (Schnittstellen), das Herzstück von TypeScript!
👉 Weiter zu Kapitel 4: Interfaces
❓ Häufig gestellte Fragen
F: Wann sollte ich Union Types verwenden?
A: Wenn eine Variable mehrere, aber begrenzte Typen annehmen kann (z.B. string | number).
F: Was ist der Unterschied zwischen type und interface?
A: Beide können für Objekt-Typen verwendet werden. interface kann erweitert werden (extends), type ist flexibler (kann Union Types, Tuples, etc. definieren).
F: Ist unknown besser als any?
A: Ja! unknown zwingt Sie, den Typ zur Laufzeit zu überprüfen, was Laufzeitfehler verhindert.
🎉 Herzlichen Glückwunsch! Sie haben Kapitel 3 abgeschlossen!
