Kodokon kodokon.com

Echten Code typisieren: DOM, fetch, JSON

Behalte an den Grenzen deiner Anwendung verlässliche Typen, dort wo DOM, Netzwerk und JSON dem Compiler entgleiten.

10 Min. · 3 Fragen

Diese Lektion in Kodokon öffnen

Echter Code beginnt dort, wo perfekte Typen enden: DOM, Netzwerk und JSON liefern Daten, die TypeScript nicht erraten kann. Erste Grenze: das DOM. querySelector liefert Element | null zurück, einen Typ, der zu vage ist, um value zu lesen oder focus() aufzurufen.

TYPESCRIPT
const input = document.querySelector<HTMLInputElement>(
  "#email"
);

if (input) {
  input.value = "test@example.com";
  input.focus();
}
Ein Typparameter bei querySelector und eine Absicherung gegen null

Der Typparameter ist ein Versprechen, das du dem Compiler gibst: Es liegt an dir, den richtigen Selektor zu treffen. Wenn das Element aus einem Event stammt, bevorzuge eine instanceof-Prüfung, die den Typ zur Laufzeit wirklich überprüft.

TYPESCRIPT
const form = document.querySelector("form");

form?.addEventListener("submit", (event) => {
  event.preventDefault();
  if (event.target instanceof HTMLFormElement) {
    console.log(new FormData(event.target));
  }
});
instanceof prüft und verengt den Typ zugleich

Zweite Grenze: das Netzwerk. response.json() liefert Promise<any> zurück, also ein offenes Tor für alles. Das professionelle Minimum: den erwarteten Typ deklarieren, response.ok prüfen und den Aufruf in einer typisierten Funktion bündeln.

TYPESCRIPT
interface Post {
  id: number;
  title: string;
}

async function getPost(id: number): Promise<Post> {
  const url = `https://api.example.com/posts/${id}`;
  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}`);
  }
  return (await response.json()) as Post;
}
Ein zentralisierter, typisierter fetch-Aufruf

Dieses as Post bleibt ein reiner Vertrauensbeweis: Wenn sich die API ändert, warnt dich zur Laufzeit nichts. Schreibe für kritische Daten einen Type Guard, der die tatsächliche Form des JSON prüft, bevor du sie verwendest.

TYPESCRIPT
function isPost(value: unknown): value is Post {
  if (typeof value !== "object" || value === null) {
    return false;
  }
  const obj = value as Record<string, unknown>;
  return (
    typeof obj.id === "number" &&
    typeof obj.title === "string"
  );
}
Ein Type Guard, der das empfangene JSON prüft (Fortsetzung des Beispiels)

Wissenscheck

Stelle sicher, dass du die wichtigsten Punkte dieser Lektion behalten hast.

  1. Welchen Rückgabetyp hat response.json() bei einer fetch-Antwort?
    • Promise<unknown>
    • Promise<any>
    • Promise<object>
    • any
  2. Warum ist event.target instanceof HTMLFormElement einer Assertion as HTMLFormElement vorzuziehen?
    • Es ist zur Laufzeit schneller
    • instanceof prüft den Typ wirklich zur Laufzeit, während as den Compiler nur zum Schweigen bringt
    • as ist im Strict-Modus verboten
  3. Was liefert document.querySelector('#email') ohne Typparameter zurück?
    • HTMLInputElement
    • Element | null
    • HTMLElement
    • null