Appearance
Kapitel 13: Häufige Fehler und Fehlerbehebung
🎯 Lernziele
In diesem Kapitel lernen Sie:
- ✅ Typenkonflikte beheben
- ✅ Fehlende Eigenschaften beheben
- ✅ Funktionsparameter-Fehler beheben
- ✅ Typableitung fehlschlägt
- ✅
anyMissbrauch vermeiden - ✅ Kompilierungsfehler beheben
13.1 Typenkonflikte
❌ Fehler
typescript
let age: number = "25"; // ❌ Fehler: Type 'string' is not assignable to type 'number'✅ Lösung
typescript
// Lösung 1: Richtigen Typ verwenden
let age: number = 25;
// Lösung 2: Typ konvertieren
let ageString: string = "25";
let ageNumber: number = Number(ageString);
// Lösung 3: Union Type verwenden (wenn beide Typen erlaubt sind)
let age: string | number = "25";
age = 25; // ✅ Erlaubt🎨 Praxis-Beispiel
typescript
// ❌ Falsch: API gibt string zurück, Sie erwarten number
function getUserId(): string {
return "123";
}
let userId: number = getUserId(); // ❌ Fehler!
// ✅ Richtig: Typ anpassen
let userId: string = getUserId();
// Oder: Konvertieren
let userIdNumber: number = Number(getUserId());13.2 Fehlende Eigenschaften
❌ Fehler
typescript
interface User {
id: number;
name: string;
email: string;
}
// ❌ Fehler: Property 'email' is missing
const user: User = {
id: 1,
name: "Max"
};✅ Lösung
typescript
// Lösung 1: Alle erforderlichen Eigenschaften hinzufügen
const user: User = {
id: 1,
name: "Max",
email: "max@example.com" // ✅ Hinzugefügt
};
// Lösung 2: Optionale Eigenschaften verwenden
interface User {
id: number;
name: string;
email?: string; // Optional
}
const user: User = {
id: 1,
name: "Max"
}; // ✅ Erlaubt🎨 Praxis-Beispiel
typescript
// ❌ Falsch: API-Response könnte fehlende Eigenschaften haben
interface ApiResponse {
success: boolean;
data: any;
message: string;
}
// Backend gibt manchmal kein 'message' zurück
const response: ApiResponse = {
success: true,
data: { ... }
}; // ❌ Fehler!
// ✅ Richtig: 'message' optional machen
interface ApiResponse {
success: boolean;
data: any;
message?: string; // Optional
}13.3 Funktionsparameter-Fehler
❌ Fehler
typescript
function greet(name: string, age: number): string {
return `Hallo ${name}, du bist ${age} Jahre alt!`;
}
// ❌ Fehler: Zu wenig Argumente
greet("Max");
// ❌ Fehler: Falscher Typ
greet("Max", "25");✅ Lösung
typescript
// Lösung 1: Richtige Anzahl und Typen von Argumenten verwenden
greet("Max", 25); // ✅ Richtig
// Lösung 2: Optionale Parameter verwenden
function greet(name: string, age?: number): string {
if (age !== undefined) {
return `Hallo ${name}, du bist ${age} Jahre alt!`;
}
return `Hallo ${name}!`;
}
greet("Max"); // ✅ Erlaubt
greet("Max", 25); // ✅ Erlaubt
// Lösung 3: Standardparameter verwenden
function greet(name: string, age: number = 0): string {
return `Hallo ${name}, du bist ${age} Jahre alt!`;
}
greet("Max"); // ✅ age = 0
greet("Max", 25); // ✅ age = 25🎨 Praxis-Beispiel
typescript
// ❌ Falsch: Zu strenge Typen
function createUser(name: string, age: number, email: string): User {
return { name, age, email };
}
// Was, wenn ich kein Alter habe?
const user = createUser("Max", ???, "max@example.com"); // ❌ Problem!
// ✅ Richtig: Optionale Parameter
function createUser(name: string, email: string, age?: number): User {
return { name, age, email };
}
const user1 = createUser("Max", "max@example.com");
const user2 = createUser("Max", "max@example.com", 25);13.4 Typableitung fehlschlägt
❌ Fehler
typescript
// TypeScript kann den Typ nicht ableiten
let data; // Typ: any (wenn "noImplicitAny" nicht aktiviert)
data = "Hallo";
console.log(data.toUpperCase()); // ✅ OK, aber keine Typsicherheit!
data = 123;
console.log(data.toUpperCase()); // ❌ Laufzeitfehler! (Aber keine Kompilierungsfehler)✅ Lösung
typescript
// Lösung 1: Explizite Typen angeben
let data: string;
data = "Hallo";
console.log(data.toUpperCase()); // ✅ OK
data = 123; // ❌ Fehler: Type 'number' is not assignable to type 'string'
// Lösung 2: Typableitung aktivieren (empfohlen!)
// In tsconfig.json:
{
"compilerOptions": {
"noImplicitAny": true // Erzwingt explizite Typen
}
}
// Jetzt muss man Typen angeben:
let data: any; // Explizit (aber besser: spezifischen Typ verwenden)🎨 Praxis-Beispiel
typescript
// ❌ Falsch: Keine Typen angegeben
function processValue(value) { // Typ: any
console.log(value.length); // Keine Fehlermeldung, aber gefährlich!
}
processValue("Hallo"); // OK
processValue([1, 2, 3]); // OK
processValue(123); // ❌ Laufzeitfehler!
// ✅ Richtig: Explizite Typen
function processValue(value: string | any[]): void {
console.log(value.length); // Sicher!
}
processValue("Hallo"); // ✅ OK
processValue([1, 2, 3]); // ✅ OK
processValue(123); // ❌ Fehler!13.5 any Missbrauch vermeiden
❌ Fehler
typescript
// ❌ Schlecht: any verwenden (verliert alle Vorteile von TypeScript)
function processData(data: any): any {
return data.someProperty.anotherProperty; // Keine Typprüfung!
}
const result = processData({ ... });
console.log(result.foo.bar); // Keine Fehlermeldung, aber gefährlich!✅ Lösung
typescript
// Lösung 1: Spezifischen Typ verwenden
interface Data {
someProperty: {
anotherProperty: string;
};
}
function processData(data: Data): string {
return data.someProperty.anotherProperty;
}
// Lösung 2: unknown verwenden (sicherer als any)
function processData(data: unknown): void {
if (typeof data === "object" && data !== null) {
const obj = data as any; // Type Assertion (vorsichtig!)
console.log(obj.someProperty);
}
}
// Lösung 3: Generics verwenden (für wiederverwendbare Funktionen)
function processData<T>(data: T): T {
return data;
}🎨 Praxis-Beispiel
typescript
// ❌ Falsch: API-Antwort mit any
async function fetchUser(): Promise<any> {
const response = await fetch("https://api.example.com/user");
return response.json();
}
const user = await fetchUser();
console.log(user.name); // Keine Autovervollständigung!
// ✅ Richtig: API-Antwort mit Interface
interface User {
id: number;
name: string;
email: string;
}
async function fetchUser(): Promise<User> {
const response = await fetch("https://api.example.com/user");
return response.json();
}
const user = await fetchUser();
console.log(user.name); // ✅ Autovervollständigung!13.6 Kompilierungsfehler beheben
❌ Häufige Fehler
1. "Cannot find module 'xxx'"
typescript
// ❌ Fehler: Cannot find module 'express'
import express from 'express';Lösung:
bash
# Typdefinitionen installieren
npm install --save-dev @types/express2. "Property 'xxx' does not exist on type 'yyy'"
typescript
interface User {
name: string;
}
const user: User = { name: "Max" };
console.log(user.age); // ❌ Fehler: Property 'age' does not exist on type 'User'Lösung:
typescript
// Lösung 1: Eigenschaft hinzufügen
interface User {
name: string;
age: number; // ✅ Hinzugefügt
}
// Lösung 2: Optionale Eigenschaft
interface User {
name: string;
age?: number; // ✅ Optional
}
// Lösung 3: Index Signature (wenn dynamische Eigenschaften erlaubt sind)
interface User {
name: string;
[key: string]: any; // ✅ Erlaubt zusätzliche Eigenschaften
}3. "Type 'xxx' is not assignable to type 'yyy'"
typescript
let age: number = "25"; // ❌ Fehler: Type 'string' is not assignable to type 'number'Lösung:
typescript
// Typ konvertieren
let age: number = Number("25"); // ✅OK
// Oder: Union Type verwenden
let age: string | number = "25";
age = 25; // ✅ Erlaubt4. "Object is possibly 'null' or 'undefined'"
typescript
function getElement(id: string): HTMLElement | null {
return document.getElementById(id);
}
const element = getElement("myDiv");
element.innerHTML = "Hallo"; // ❌ Fehler: Object is possibly 'null'Lösung:
typescript
// Lösung 1: Null-Prüfung
const element = getElement("myDiv");
if (element !== null) {
element.innerHTML = "Hallo"; // ✅ Sicher
}
// Lösung 2: Optional Chaining
const element = getElement("myDiv");
element?.innerHTML = "Hallo"; // ✅ Sicher (macht aber nichts, wenn null)
// Lösung 3: Non-Null Assertion (vorsichtig!)
const element = getElement("myDiv")!;
element.innerHTML = "Hallo"; // ✅ OK (aber gefährlich, wenn wirklich null)13.7 tsconfig.json Fehler beheben
❌ Häufige Fehler
1. "Cannot write file 'xxx' because it would overwrite input file"
Ursache: outDir und rootDir zeigen auf dasselbe Verzeichnis.
Lösung:
json
{
"compilerOptions": {
"rootDir": "./src", // Quelldateien
"outDir": "./dist" // Kompilierte Dateien (müssen unterschiedlich sein!)
}
}2. "Include paths must not refer to files or folders outside the baseUrl"
Ursache: Falsche Pfadangaben in tsconfig.json.
Lösung:
json
{
"compilerOptions": {
"baseUrl": ".", // Basisverzeichnis
"paths": {
"@/*": ["src/*"] // Korrekte Pfadangabe
}
}
}13.8 Praxis: Fehlerbehebung in einem Projekt
💻 Vollständiges Beispiel
typescript
// ❌ Code mit Fehlern
// math.ts
export function add(a: number, b: number): number {
return a + b;
}
export function subtract(a: number, b): number { // ❌ Parameter 'b' hat implizit den Typ 'any'
return a - b;
}
// main.ts
import { add, subtract } from './math';
const result1 = add(5, "3"); // ❌ Fehler: Argument 2 hat den Typ 'string'
const result2 = subtract(5, 3);
console.log(result1);
console.log(result2);
// ✅ Behobener Code
// math.ts
export function add(a: number, b: number): number {
return a + b;
}
export function subtract(a: number, b: number): number { // ✅ Typ hinzugefügt
return a - b;
}
// main.ts
import { add, subtract } from './math';
const result1 = add(5, 3); // ✅ Richtig
const result2 = subtract(5, 3);
console.log(result1); // Ausgabe: 8
console.log(result2); // Ausgabe: 2📝 Zusammenfassung
In diesem Kapitel haben Sie gelernt:
- ✅ Typenkonflikte beheben (Typen anpassen, konvertieren, Union Types verwenden)
- ✅ Fehlende Eigenschaften beheben (alle Eigenschaften hinzufügen oder optional machen)
- ✅ Funktionsparameter-Fehler beheben (optionale Parameter, Standardparameter)
- ✅ Typableitung aktivieren (
noImplicitAny) - ✅
anyMissbrauch vermeiden (spezifische Typen,unknown, Generics) - ✅ Kompilierungsfehler beheben (Modulfehler, Eigenschaftsfehler, etc.)
- ✅
tsconfig.jsonFehler beheben (rootDir,outDir,paths)
🎯 Nächstes Kapitel
Herzlichen Glückwunsch! Sie haben alle Kapitel der TypeScript-Tutorial-Serie abgeschlossen! 🎉
Sie können jetzt:
- ✅ TypeScript sicher verwenden
- ✅ Komplexe Projekte mit TypeScript erstellen
- ✅ Fehler effizient beheben
Viel Erfolg bei Ihren TypeScript-Projekten! 💪
❓ Häufig gestellte Fragen
F: Warum erhalte ich immer "Cannot find module" Fehler?
A: Stellen Sie sicher, dass Sie die entsprechenden Typdefinitionen installiert haben (@types/xxx).
F: Wie vermeide ich any?
A:
- Aktivieren Sie
noImplicitAnyintsconfig.json - Verwenden Sie spezifische Typen
- Verwenden Sie
unknownstattany - Verwenden Sie Generics für wiederverwendbare Funktionen
F: Warum kann TypeScript manche Fehler nicht erkennen?
A: TypeScript ist ein statischer Typenprüfer. Einige Fehler treten erst zur Laufzeit auf. Verwenden Sie immer strikte Einstellungen ("strict": true).
🎉 Herzlichen Glückwunsch! Sie haben Kapitel 13 und das gesamte TypeScript-Tutorial abgeschlossen! 🎉
