TypeScript Fortgeschritten

TypeScript für JavaScript-Entwickler

TypeScript ist JavaScript mit Superkräften. Es fügt Typen hinzu, die Fehler finden, bevor dein Code läuft.

Warum TypeScript?

Stell dir vor, du hast diesen JavaScript-Code:

function greet(user) {
    return "Hallo, " + user.name;
}

greet("Max"); // 💥 Fehler zur Laufzeit!

Der Fehler wird erst sichtbar, wenn das Programm läuft. Mit TypeScript:

function greet(user: { name: string }) {
    return "Hallo, " + user.name;
}

greet("Max"); // ❌ Fehler sofort im Editor!

TypeScript einrichten

Installation

npm install -g typescript

Projekt initialisieren

tsc --init

Kompilieren

tsc datei.ts
# Erstellt datei.js

Grundlegende Typen

// Primitive Typen
const name: string = "Anna";
const alter: number = 25;
const istAktiv: boolean = true;

// Arrays
const zahlen: number[] = [1, 2, 3];
const namen: string[] = ["Max", "Anna"];

// Alternative Array-Syntax
const punkte: Array<number> = [10, 20, 30];

Funktionen typisieren

// Parameter und Rückgabewert
function addiere(a: number, b: number): number {
    return a + b;
}

// Arrow Function
const multipliziere = (a: number, b: number): number => a * b;

// Optionale Parameter
function gruss(name: string, titel?: string): string {
    if (titel) {
        return `Hallo, ${titel} ${name}!`;
    }
    return `Hallo, ${name}!`;
}

// Default-Werte
function countdown(start: number = 10): void {
    console.log(start);
}

Interfaces

Interfaces definieren die Form von Objekten:

interface User {
    id: number;
    name: string;
    email: string;
    alter?: number; // Optional
}

function createUser(user: User): User {
    return user;
}

const neuerUser = createUser({
    id: 1,
    name: "Max",
    email: "max@example.com"
});

Interface erweitern

interface Person {
    name: string;
    alter: number;
}

interface Mitarbeiter extends Person {
    position: string;
    gehalt: number;
}

const dev: Mitarbeiter = {
    name: "Anna",
    alter: 28,
    position: "Frontend Developer",
    gehalt: 55000
};

Type Aliases

// Für primitive Typen
type ID = string | number;

// Für Objekte
type Point = {
    x: number;
    y: number;
};

// Union Types
type Status = "pending" | "success" | "error";

function setStatus(status: Status) {
    console.log(status);
}

setStatus("success"); // ✅
setStatus("unknown"); // ❌ Fehler!

Generics

Generics machen Code wiederverwendbar:

// Ohne Generics - unflexibel
function firstNumber(arr: number[]): number {
    return arr[0];
}

// Mit Generics - flexibel
function first<T>(arr: T[]): T {
    return arr[0];
}

first([1, 2, 3]);        // Typ: number
first(["a", "b", "c"]);  // Typ: string

Generics mit Constraints

interface HasLength {
    length: number;
}

function logLength<T extends HasLength>(item: T): void {
    console.log(item.length);
}

logLength("Hallo");     // ✅ String hat length
logLength([1, 2, 3]);   // ✅ Array hat length
logLength(123);         // ❌ Number hat kein length

Praktisches Beispiel: API-Response

interface ApiResponse<T> {
    data: T;
    status: number;
    message: string;
}

interface User {
    id: number;
    name: string;
    email: string;
}

async function fetchUser(id: number): Promise<ApiResponse<User>> {
    const response = await fetch(`/api/users/${id}`);
    return response.json();
}

// Verwendung
const result = await fetchUser(1);
console.log(result.data.name); // TypeScript kennt den Typ!

TypeScript in React

interface ButtonProps {
    text: string;
    onClick: () => void;
    disabled?: boolean;
}

function Button({ text, onClick, disabled = false }: ButtonProps) {
    return (
        <button onClick={onClick} disabled={disabled}>
            {text}
        </button>
    );
}

Nützliche Utility Types

// Partial - alle Properties optional
interface User {
    name: string;
    email: string;
}

type PartialUser = Partial<User>;
// { name?: string; email?: string; }

// Required - alle Properties required
type RequiredUser = Required<PartialUser>;

// Pick - nur bestimmte Properties
type UserName = Pick<User, "name">;
// { name: string; }

// Omit - Properties ausschließen
type UserWithoutEmail = Omit<User, "email">;
// { name: string; }

Tipps für den Einstieg

  1. Strenge Einstellungen aktivieren in tsconfig.json:

    {
        "strict": true
    }
  2. any vermeiden - Es hebelt TypeScript aus

  3. Klein anfangen - Typisiere erstmal nur neue Dateien

  4. IDE nutzen - VS Code hat exzellente TypeScript-Unterstützung

Fazit

TypeScript macht dich produktiver:

  • Fehler werden früh gefunden
  • Bessere Autovervollständigung
  • Code ist selbst-dokumentierend
  • Refactoring wird sicherer

Der Lernaufwand lohnt sich - probier es aus!