Appearance
Kapitel 12: Häufig gestellte Interviewfragen zu TypeScript
🎯 Lernziele
In diesem Kapitel lernen Sie:
- ✅ Unterschied zwischen TypeScript und JavaScript
- ✅
anyvsunknown - ✅
interfacevstype - ✅ Bedeutung von Generics
- ✅ Häufig verwendete Tool-Typen
- ✅ Enums, Tuples, Union Types Anwendungsfälle
- ✅ Warum
anyvermieden werden sollte
12.1 Was ist der Unterschied zwischen TypeScript und JavaScript?
📝 Antwort
| Merkmal | JavaScript | TypeScript |
|---|---|---|
| Typensystem | Dynamisch | Statisch (optional) |
| Fehlererkennung | Zur Laufzeit | Zur Kompilierungszeit |
| IDE-Unterstützung | Basis | Hervorragend (IntelliSense) |
| Kompilierung | Nicht erforderlich | Erforderlich (tsc) |
| Lernkurve | Niedriger | Höher (erfordert JS-Kenntnisse) |
| Skalierbarkeit | Schwieriger bei großen Projekten | Besser (Typsicherheit) |
💻 Code-Beispiel
typescript
// JavaScript - Fehler wird zur Laufzeit entdeckt
function add(a, b) {
return a + b;
}
console.log(add(5, "10")); // Ausgabe: "510" (Fehler!)
// TypeScript - Fehler wird zur Kompilierungszeit entdeckt
function addTS(a: number, b: number): number {
return a + b;
}
console.log(addTS(5, "10")); // ❌ Kompilierungsfehler!12.2 Was ist der Unterschied zwischen any und unknown?
📝 Antwort
| Merkmal | any | unknown |
|---|---|---|
| Typsicherheit | Keine | Vollständig |
| Direkter Zugriff | Erlaubt | Verboten |
| Type Guards erforderlich | Nein | Ja |
| Empfehlung | Vermeiden | Verwenden statt any |
💻 Code-Beispiel
typescript
// any (Unsicher)
let anyValue: any = "Hallo";
anyValue.foo.bar(); // Keine Fehlermeldung zur Kompilierungszeit!
console.log(anyValue.length); // Könnte Laufzeitfehler verursachen
// 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
}
// ✅ Type Assertion (Vorsicht!)
console.log((unknownValue as string).length); // OK, aber gefährlich!💡 Best Practice
typescript
// ❌ Schlecht: any verwenden
function processData(data: any): void {
console.log(data.toUpperCase()); // Könnte fehlschlagen!
}
// ✅ Gut: unknown verwenden
function processDataSafe(data: unknown): void {
if (typeof data === "string") {
console.log(data.toUpperCase()); // Sicher!
}
}12.3 Was ist der Unterschied zwischen interface und type?
📝 Antwort
| Merkmal | interface | type |
|---|---|---|
| Objekttypen | ✅ | ✅ |
| Vererbung | extends | & (Intersection) |
| Union Types | ❌ | ✅ |
| Primitive Typen | ❌ | ✅ |
| Declaration Merging | ✅ (automatisch) | ❌ |
| Tuples | ❌ | ✅ |
| Mapped Types | ❌ | ✅ |
💻 Code-Beispiel
typescript
// Interface: Vererbung
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
// Type: Intersection
type Animal = {
name: string;
};
type Dog = Animal & {
breed: string;
};
// Type: Union Type (Interface kann das nicht)
type Status = "pending" | "success" | "error";
// Type: Primitive Typen (Interface kann das nicht)
type ID = string | number;
// Interface: Declaration Merging (Type kann das nicht)
interface User {
name: string;
}
interface User { // Wird zusammengeführt!
age: number;
}
// User hat jetzt name UND age💡 Empfehlung
- Verwenden Sie
interfacefür: Objekttypen, die erweitert werden können - Verwenden Sie
typefür: Union Types, Primitive Typen, Tuples, komplexe Typkombinationen
12.4 Was ist der Zweck von Generics?
📝 Antwort
Generics ermöglichen typsichere, wiederverwendbare Funktionen und Klassen, die mit verschiedenen Typen arbeiten können.
💻 Code-Beispiel
typescript
// ❌ Schlecht: any verwenden (verliert Typsicherheit)
function identity1(arg: any): any {
return arg;
}
let result1 = identity1("Hallo");
// result1 ist vom Typ any (keine Autovervollständigung!)
// ✅ Gut: Generics verwenden
function identity2<T>(arg: T): T {
return arg;
}
let result2 = identity2("Hallo");
// result2 ist vom Typ string (volle Typsicherheit!)
// Praxis-Beispiel: Generische API-Antwort
interface ApiResponse<T> {
success: boolean;
data: T;
message?: string;
}
// Kann mit verschiedenen Datentypen verwendet werden
const userResponse: ApiResponse<User> = { ... };
const productResponse: ApiResponse<Product> = { ... };💡 Vorteile von Generics
- Typsicherheit: Behält Typinformationen bei
- Wiederverwendbarkeit: Ein einziger Code für mehrere Typen
- Lesbarkeit: Bessere Dokumentation
- Wartbarkeit: Leichteres Refactoring
12.5 Welche häufig verwendeten Tool-Typen kennen Sie?
📝 Antwort
| Tool-Typ | Beschreibung | Beispiel |
|---|---|---|
Partial<T> | Macht alle Eigenschaften optional | Partial<User> |
Required<T> | Macht alle Eigenschaften pflicht | Required<User> |
Readonly<T> | Macht alle Eigenschaften schreibgeschützt | Readonly<User> |
Pick<T, K> | Wählt bestimmte Eigenschaften aus | Pick<User, "id" | "name"> |
Omit<T, K> | Entfernt bestimmte Eigenschaften | Omit<User, "password"> |
Exclude<T, U> | Entfernt Typen aus Union | Exclude<"a" | "b" | "c", "a"> |
Extract<T, U> | Extrahiert Typen aus Union | Extract<"a" | "b" | "c", "a"> |
ReturnType<T> | Extrahiert Rückgabetyp einer Funktion | ReturnType<typeof myFunc> |
💻 Code-Beispiel
typescript
interface User {
id: number;
name: string;
age: number;
email: string;
password: string;
}
// Partial: Alles optional machen
type PartialUser = Partial<User>;
// { id?: number; name?: string; ... }
// Pick: Nur bestimmte Eigenschaften auswählen
type UserNameAndId = Pick<User, "id" | "name">;
// { id: number; name: string; }
// Omit: Bestimmte Eigenschaften ausschließen
type PublicUser = Omit<User, "password">;
// { id: number; name: string; age: number; email: string; }
// ReturnType: Rückgabetyp extrahieren
function createUser() {
return { id: 1, name: "Max" };
}
type CreateUserReturn = ReturnType<typeof createUser>;
// { id: number; name: string; }12.6 Wann sollten Sie Enums, Tuples und Union Types verwenden?
📝 Antwort
Enums – Für benannte Konstanten
typescript
// ✅ Gut: Enums verwenden für begrenzte Werte
enum Direction {
North = "NORTH",
South = "SOUTH",
East = "EAST",
West = "WEST"
}
function move(direction: Direction): void {
console.log(`Gehe nach ${direction}`);
}
move(Direction.North); // ✅ Typsicher!Tuples – Für befeste Elementanzahl mit bekannten Typen
typescript
// ✅ Gut: Tuples verwenden für befeste Strukturen
let person: [string, number] = ["Max", 25];
// Beispiel: API-Antwort mit Status und Daten
function fetchData(): [boolean, any] {
try {
const data = { name: "Max" };
return [true, data];
} catch {
return [false, null];
}
}
const [success, data] = fetchData();Union Types – Für Werte, die mehrere Typen annehmen können
typescript
// ✅ Gut: Union Types verwenden für begrenzte Typen
type Status = "pending" | "success" | "error";
type ID = string | number;
function processId(id: ID): void {
if (typeof id === "string") {
console.log(id.toUpperCase());
} else {
console.log(id.toFixed(2));
}
}12.7 Warum sollten Sie die Verwendung von any vermeiden?
📝 Antwort
- Verliert Typsicherheit: TypeScript kann Fehler nicht erkennen
- Keine Autovervollständigung: IDE kann keine Vorschläge machen
- Laufzeitfehler: Fehler werden erst zur Laufzeit entdeckt
- Schlechte Dokumentation: Code wird schwer zu verstehen
- Verliert Vorteile von TypeScript: Eigentlich programmieren Sie in JavaScript
💻 Code-Beispiel
typescript
// ❌ Schlecht: any verwenden
function processDataBad(data: any): void {
console.log(data.toUpperCase()); // Keine Fehlermeldung!
}
processDataBad(123); // Laufzeitfehler: data.toUpperCase is not a function
// ✅ Gut: unknown verwenden
function processDataGood(data: unknown): void {
if (typeof data === "string") {
console.log(data.toUpperCase()); // Sicher!
}
}
// ✅ Noch besser: Spezifischen Typ verwenden
function processDataBest(data: string): void {
console.log(data.toUpperCase()); // Vollständig typsicher!
}💡 Best Practices
typescript
// ❌ Vermeiden
let value: any;
// ✅ Besser: unknown verwenden
let value: unknown;
// ✅ Am besten: Spezifischen Typ verwenden
let value: string;
// ✅ Oder: Union Type verwenden
let value: string | number;📝 Zusammenfassung
In diesem Kapitel haben Sie gelernt:
- ✅ TypeScript vs JavaScript: Statische vs dynamische Typen
- ✅
anyvsunknown: Unsicher vs sicher - ✅
interfacevstype: Wann welches verwenden? - ✅ Generics: Typsichere Wiederverwendbarkeit
- ✅ Tool-Typen:
Partial,Pick,Omit, etc. - ✅ Enums, Tuples, Union Types: Anwendungsfälle
- ✅
anyvermeiden: Warum und Alternativen
🎯 Nächstes Kapitel
Im Kapitel 13 lernen wir häufige Fehler und Fehlerbehebung in TypeScript!
👉 Weiter zu Kapitel 13: Häufige Fehler
❓ Häufig gestellte Fragen
F: Muss ich interface oder type verwenden?
A: Für Objekttypen: interface (bessere Erweiterbarkeit). Für Union Types, Primitive Typen: type.
F: Ist any böse?
A: Nein, aber es sollte vermieden werden. Verwenden Sie unknown oder spezifische Typen.
F: Wann sollte ich Generics verwenden?
A: Wenn Sie Funktionen oder Klassen schreiben, die mit verschiedenen Typen arbeiten sollen, aber dabei typsicher bleiben wollen.
🎉 Herzlichen Glückwunsch! Sie haben Kapitel 12 abgeschlossen!
