Hirefullstack – Software Engineering & IT-Beratung aus Berlin
← Zur Übersicht
Einstieg 13 Min Lesezeit

TypeScript, so viel du brauchst

Die Schreibweisen, die dir in React-Code ständig begegnen

In einem Satz

TypeScript ist JavaScript, bei dem du dazuschreibst, welche Form deine Daten haben. Der Editor meckert dann, bevor der Browser es tut.

Du kannst JavaScript – dann fehlt dir hier erstaunlich wenig. Eine Handvoll Schreibweisen deckt fast alles ab, was in React-Projekten vorkommt.

Bildlich gesprochen

Typen sind kein zweites Programm. Sie sind Kommentare, die überprüft werden. Vor dem Ausführen fliegen sie raus – im Browser läuft ganz normales JavaScript.

Die Grundform: Wert : Typ

grundlagen.ts
let name: string = "Ada";
let alter: number = 36;
let aktiv: boolean = true;
let tags: string[] = ["react", "ts"];      // Array aus Strings

// Meistens brauchst du das gar nicht – TypeScript errät es selbst:
let titel = "Hallo";       // ist automatisch string
// titel = 42;             // Fehler: eine Zahl passt hier nicht

// Funktionen: was rein geht, was raus kommt
function verdopple(n: number): number {
  return n * 2;
}

const kuerze = (text: string, max = 20): string =>
  text.length > max ? text.slice(0, max) + "…" : text;
Tipp Weniger tippen ist besser

Schreib Typen nur an die Grenzen: Props, Funktionsparameter, Daten von einer API. Innendrin errät TypeScript sie selbst (InferenzTypeScript errät den Typ selbst, ohne dass du ihn hinschreibst.). const x: number = 5 ist unnötiger Lärm.

Objekte beschreiben

objekte.ts
type User = {
  id: string;
  name: string;
  email?: string;      // das ? heißt: darf fehlen
};

// Zwei Typen zusammenlegen:
type Admin = User & { rechte: string[] };

// interface kann fast dasselbe:
interface Product {
  id: string;
  price: number;
}

`type` oder `interface`? Für React-Props fast egal. Faustregel: nimm type – es kann alles, was interface kann, und noch mehr.

Union: „eines von diesen“

Eine Union„Eines von diesen“: string | number heißt, der Wert ist entweder eine Zeichenkette oder eine Zahl. listet die erlaubten Möglichkeiten auf. Mit festen Wörtern wird daraus eine Auswahl, die dein Editor automatisch vervollständigt.

unions.ts
type Variante = "primary" | "ghost" | "danger";
type Id = string | number;

let v: Variante = "ghost";     // ok
// let w: Variante = "blau";   // Fehler – gibt es nicht
Tipp Das nützlichste Muster in React

Statt drei Wahrheitswerten (laedt, hatFehler, fertig), die sich widersprechen können, beschreibst du die Zustände einzeln. Dann ist ein unmöglicher Zustand gar nicht mehr hinschreibbar.

zustand.ts
type Zustand =
  | { status: "laedt" }
  | { status: "fehler"; text: string }
  | { status: "fertig"; daten: string[] };

function anzeigen(z: Zustand) {
  if (z.status === "laedt") return "Lädt …";
  if (z.status === "fehler") return z.text;      // text gibt es hier sicher
  return z.daten.length + " Treffer";            // daten gibt es hier sicher
}
Das gemeinsame Feld status verrät TypeScript, welche Variante gerade vorliegt – es kennt danach genau die passenden Felder.
Gut zu wissen Wie das heißt

Fachbegriff: Discriminated UnionMehrere Varianten mit einem gemeinsamen Erkennungsfeld – daran sieht TypeScript, welche Variante gerade vorliegt.Beispiel: { status: "laden" } oder { status: "fehler", text: string }. Fragst du status ab, weiß TypeScript, welche Felder es gibt.. Und das Eingrenzen durch die Abfrage heißt NarrowingTypeScript grenzt einen Typ ein, wenn du ihn abfragst: nach if (typeof x === "number") weiß es, dass x eine Zahl ist.. Die Namen musst du nicht behalten – das Muster schon.

Fertige Helfer, die du oft siehst

utilities.ts
type User = { id: string; name: string; email: string };

Partial<User>              // alle Felder optional      -> für Updates
Pick<User, "id" | "name">  // nur diese beiden Felder
Omit<User, "email">        // alles außer email         -> sehr häufig
Record<string, number>     // Objekt: Text-Schlüssel, Zahl-Wert

keyof User                 // "id" | "name" | "email"
Solche Helfer heißen Utility Types – sie bauen aus einem Typ einen neuen.
Genauer erklärt: Generics, as const, satisfies und unknown optional

Generics – ein Platzhalter für einen Typ

Ein GenericEin Platzhalter für einen Typ, der erst beim Benutzen festgelegt wird – das <T> in Array<T>. ist eine Variable für Typen. Du kennst das schon aus useState<number>(0). Selbst schreiben musst du sie selten, lesen können solltest du sie.

generics.ts
// T wird erst beim Aufruf festgelegt
function erstes<T>(items: T[]): T | undefined {
  return items[0];
}

erstes([1, 2, 3]);      // T = number
erstes(["a", "b"]);     // T = string

// Mit Bedingung: T muss ein id-Feld haben
function nachId<T extends { id: string }>(items: T[], id: string) {
  return items.find((i) => i.id === id);
}

as const – Werte einfrieren

wird zu string aufgeweicht
const ROLLEN = ["admin", "user"];
// Typ: string[]

type Rolle = (typeof ROLLEN)[number];
// -> string  (nutzlos)
bleibt exakt
const ROLLEN = ["admin", "user"] as const;
// Typ: readonly ["admin", "user"]

type Rolle = (typeof ROLLEN)[number];
// -> "admin" | "user"  ✨

So leitest du Typen aus deinen Daten ab, statt beides doppelt zu pflegen.

satisfies – prüfen, ohne zu vergröbern

satisfies.ts
type Theme = Record<string, string>;

const theme = {
  bg: "#0a0c11",
  ink: "#e8ebf4",
} satisfies Theme;

theme.bg;      // der Editor kennt bg und ink
// theme.foo;  // Fehler – gibt es nicht

// Mit ": Theme" statt "satisfies Theme" wäre theme.foo durchgegangen.

unknown statt any

any schaltet die Prüfung ab – überall dort, wo der Wert danach noch hinfließt. unknown sagt „ich weiß es noch nicht“ und zwingt dich, vorher nachzusehen.

unknown.ts
try {
  riskant();
} catch (err) {           // err ist unknown, nicht Error!
  const text = err instanceof Error ? err.message : "Unbekannter Fehler";
  console.error(text);
}
Achtung Typen sind zur Laufzeit weg

TypeScript prüft vorher und wird dann herausgeworfen. Daten von einer API sind also nicht automatisch korrekt, nur weil du sie User genannt hast. Wer das absichern will, prüft zur Laufzeit – zum Beispiel mit Zod.

Sitzt das schon?

5 Fragen zu dieser Lektion. Falsche Antworten landen in deiner Statistik.

Jetzt selbst schreiben

Zustände sauber beschreiben

Die Komponente zeigt einen Ladezustand an – aktuell mit any verkabelt und ohne Ausgabe. Sorge dafür, dass jeder Zustand die richtige Anzeige erzeugt.

  • Bei laedt erscheint Lädt …
  • Bei fehler erscheint der Text aus text
  • Bei fertig erscheint N Treffer (N = Länge von daten)
  • Bonus: ersetze any durch eine Union aus drei Varianten
type Zustand = any; // TODO: durch eine Union aus drei Varianten ersetzen

export function Anzeige({ z }: { z: Zustand }) {
  // TODO: pro Zustand die richtige Ausgabe zurückgeben
  return <p>???</p>;
}

export default function App() {
  return (
    <div style={{ fontFamily: "system-ui", padding: 16 }}>
      <Anzeige z={{ status: "laedt" }} />
      <Anzeige z={{ status: "fehler", text: "Server weg" }} />
      <Anzeige z={{ status: "fertig", daten: ["a", "b", "c"] }} />
    </div>
  );
}

Hirefullstack

Ihr braucht React-Verstärkung im Team?

Wir bauen seit Jahren React- und Next.js-Anwendungen für Kunden in ganz Deutschland – als einzelner Experte, als Verstärkung fürs Bestandsteam oder als komplettes Scrum-Team.

Projekt besprechen →