TypeScript Crashkurs für React-Entwickler
Die wichtigsten TypeScript-Konzepte, die du wirklich brauchst – ohne den Overhead eines kompletten Sprachkurses.
JavaScript ist flexibel – manchmal zu flexibel. Ein undefined in einem Prop, eine falsch formatierte API-Response, ein Typo im Eigenschaftsnamen: In größeren React-Projekten werden solche Fehler zur echten Zeitfalle, weil sie erst im Browser auftauchen, oft weit entfernt von der Stelle, die das Problem verursacht hat.
TypeScript löst das, indem es deinen Code zur Build-Zeit prüft. Kein Versprechen auf null Bugs – aber die Klasse von Fehlern, die aus falsch übergebenen oder fehlenden Daten entsteht, wird deutlich kleiner.
Hier kommen die Konzepte, die du für den Alltag mit React wirklich brauchst.
Grundtypen – schnell abgehakt
Der einfachste Einstieg: Variablen bekommen einen Typ.
const name: string = "Max"
const age: number = 28
const isLoggedIn: boolean = false
const tags: string[] = ["react", "typescript"]
In der Praxis schreibst du die meisten dieser Annotations gar nicht – TypeScript inferiert den Typ aus dem Initialwert:
const name = "Max" // TypeScript weiß: string
const age = 28 // TypeScript weiß: number
Faustregel: Schreib Typ-Annotations nur dort, wo TypeScript nicht von allein drauf kommt oder wo sie die Lesbarkeit für andere erhöht.
Props typisieren – der häufigste Anwendungsfall
Das ist das Konzept, mit dem du in React täglich zu tun hast. Statt Props einfach durchzureichen, definierst du vorher, was eine Komponente erwartet:
interface ButtonProps {
label: string
onClick: () => void
variant?: "primary" | "ghost"
disabled?: boolean
}
export function Button({ label, onClick, variant = "primary", disabled = false }: ButtonProps) {
return (
<button
onClick={onClick}
disabled={disabled}
className={variant === "primary" ? "btn-primary" : "btn-ghost"}
>
{label}
</button>
)
}
Das ? bei variant und disabled bedeutet: optional. Wer den Button verwendet, muss diese Props nicht übergeben. Fehlt dagegen label oder onClick, zeigt TypeScript sofort einen Fehler – im Editor, nicht erst wenn die App abstürzt.
useState mit Typen
Für einfache Werte braucht TypeScript keine Hilfe:
const [isOpen, setIsOpen] = useState(false) // inferiert: boolean
const [query, setQuery] = useState("") // inferiert: string
Sobald der Startzustand null oder ein komplexes Objekt ist, hilfst du nach:
interface User {
id: number
name: string
email: string
}
const [user, setUser] = useState<User | null>(null)
Jetzt weiß TypeScript: user ist entweder ein User-Objekt oder null. Wenn du ohne vorherige Null-Prüfung auf user.name zugreifst, meckert der Editor sofort. Das klingt lästig – bis du das erste Mal einen 3-Uhr-nachts-Bug damit vermeidest.
Events richtig tippen
Event-Handler sind der häufigste Stolperstein für TypeScript-Einsteiger. Das Pattern ist einfach, aber du musst es einmal gesehen haben:
function SearchInput() {
const [value, setValue] = useState("")
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value)
}
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault()
// Suchanfrage verarbeiten
}
return (
<form onSubmit={handleSubmit}>
<input value={value} onChange={handleChange} />
</form>
)
}
Den genauen Typ musst du nicht auswendig lernen. Schreib event: und lass den Editor autocomplete-Vorschläge machen – oder hover kurz über den inline-Handler, den du ohnehin schon hast. VS Code zeigt dir den Typ direkt.
Union Types: Exakt statt grob
Ein Union Type gibt vor, welche Werte wirklich erlaubt sind – nicht nur, welcher Datentyp gemeint ist:
type Status = "idle" | "loading" | "success" | "error"
interface FetchState {
status: Status
data?: string[]
errorMessage?: string
}
Schreibst du irgendwo im Code status === "lodaing" (Typo), zeigt TypeScript den Fehler. Ein normaler string-Typ hätte das still durchgelassen und du hättest eine Stunde lang nach dem Bug gesucht.
interface vs. type – eine ehrliche Einschätzung
Die TypeScript-Community streitet darüber seit Jahren. Für React-Props-Definitionen sind interface und type praktisch identisch – du wirst keinen Unterschied merken.
interface eignet sich gut für erweiterbare Strukturen:
interface Animal { name: string }
interface Dog extends Animal { breed: string }
type ist flexibler für Union Types und Aliases:
type Result = Success | Error
type ID = string | number
Meine persönliche Präferenz: interface für Props und Datenstrukturen, type für Unions. Das ist eine Konvention, keine technische Notwendigkeit. Entscheidet euch im Team auf eine Variante und haltet sie durch – der Streit selbst ist nicht die Energie wert.
Häufiger Anfängerfehler: zu früh zu weit
TypeScript hat einen Ruf als schwierig, der teils berechtigt ist – aber aus dem falschen Grund. Die Grundlagen, die du für 80 % deiner React-Arbeit brauchst, lernst du schnell. Aber TypeScript kann tief gehen: Conditional Types, Mapped Types, Template Literal Types – das ist ein eigenes Kaninchenloch, das du zu Beginn nicht brauchst.
Der typische Fehler: Alles sofort "korrekt" typisieren wollen, dann irgendwo any schreiben (der Notausgang, der alle Typ-Checks abschaltet) und sich fragen, wozu das Ganze überhaupt gut ist.
Bessere Strategie: Fang mit Props-Interfaces und useState an. Lass TypeScript dort inferieren, wo es das kann. Greif zu komplexeren Konstrukten erst dann, wenn du einen konkreten Problemdruck hast – nicht weil ein Tutorial sagt, dass du musst.
Nächste Schritte
Wenn du Next.js 15 verwendest: Das Framework kommt bereits mit TypeScript vorkonfiguriert. Starte einfach mit .tsx-Dateien, alles andere läuft automatisch.
Weiterführende Artikel zu Next.js Portfolio-Setup und Supabase-Integration sind in Vorbereitung und werden hier verlinkt, sobald sie veröffentlicht sind.
FAQ zu diesem Artikel
d6benjamin
Willkommen auf d6b