EMZETT.
Login

Kurz: Für den Browser brauchst du in der tsconfig.json die Bibliothek DOM. Dann kennt TypeScript alle Elemente und Ereignisse:

Teil des Kurses TypeScript

Kapitel 12 von 15 im Kurs TypeScript. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

DOM mit Typen

Für den Browser brauchst du in der tsconfig.json die Bibliothek DOM. Dann kennt TypeScript alle Elemente und Ereignisse:

const knopf = document.querySelector("button");            // HTMLButtonElement | null
const feld = document.querySelector<HTMLInputElement>("#name");   // Typ angeben
 
knopf?.addEventListener("click", (ereignis) => {            // ereignis: MouseEvent
  console.log(ereignis.clientX, feld?.value);
});
 
const liste = document.getElementById("liste");             // HTMLElement | null
if (liste) {
  const li = document.createElement("li");
  li.textContent = "Neuer Eintrag";
  liste.append(li);
}

querySelector kann null zurückgeben. Mit strict musst du das behandeln (?., if, oder eine Hilfsfunktion):

function waehle<T extends Element>(selektor: string, wurzel: ParentNode = document): T {
  const el = wurzel.querySelector<T>(selektor);
  if (!el) throw new Error(`Element nicht gefunden: ${selektor}`);
  return el;
}
const eingabe = waehle<HTMLInputElement>("#name");
eingabe.value = "Mia";

Wichtige Typen: HTMLElement, HTMLInputElement, HTMLFormElement, HTMLCanvasElement, Event, MouseEvent, KeyboardEvent, SubmitEvent, FormData.

const form = document.querySelector<HTMLFormElement>("form");
form?.addEventListener("submit", (e: SubmitEvent) => {
  e.preventDefault();
  const daten = new FormData(form);
  const name = String(daten.get("name") ?? "");     // get liefert FormDataEntryValue | null
  console.log(name);
});
 
document.addEventListener("keydown", (e: KeyboardEvent) => {
  if (e.key === "Escape") console.log("Abbrechen");
});

Node.js mit Typen

Installiere die Typen für Node.js:

npm install -D typescript @types/node
import { readFile, writeFile } from "node:fs/promises";
import { join } from "node:path";
import process from "node:process";
 
interface Konfig { name: string; port: number }
 
async function ladeKonfig(pfad: string): Promise<Konfig> {
  const text = await readFile(pfad, "utf8");
  const daten: unknown = JSON.parse(text);
  // ... prüfen, siehe Kapitel Laufzeitprüfung
  return daten as Konfig;
}
 
const ziel = join(process.cwd(), "konfig.json");
console.log(ziel.endsWith("konfig.json"));

Ausgabe:

true

Die Typen heißen @types/<paket> (DefinitelyTyped). Viele Bibliotheken liefern ihre Typen inzwischen selbst mit.

Ein kleiner Server mit Typen

import { createServer, IncomingMessage, ServerResponse } from "node:http";
 
function behandle(anfrage: IncomingMessage, antwort: ServerResponse): void {
  antwort.setHeader("Content-Type", "application/json; charset=utf-8");
  antwort.end(JSON.stringify({ pfad: anfrage.url, methode: anfrage.method }));
}
createServer(behandle).listen(3000);

Mit Frameworks wie Express (@types/express), Fastify oder Hono bekommst du typisierte Routen, Anfrage- und Antwortobjekte.

Browser und Node im selben Projekt

Browser-Typen (DOM) und Node-Typen (@types/node) enthalten teils konkurrierende Namen. Trenne Projektteile mit eigenen tsconfig-Dateien (tsconfig.app.json und tsconfig.node.json), wie Vite-Vorlagen es tun.

React mit TypeScript (Ausblick)

type Props = { titel: string; aktiv?: boolean; beiKlick: () => void };
 
function Karte({ titel, aktiv = false, beiKlick }: Props) {
  return <button onClick={beiKlick} aria-pressed={aktiv}>{titel}</button>;
}
 
const [zaehler, setZaehler] = useState<number>(0);

Props, Zustände und Ereignisse sind in React-Projekten vollständig typisiert. Dasselbe gilt für Vue (mit <script setup lang="ts">), Svelte und Angular (TypeScript ist dort Standard).

Umgebungs-Typen ergänzen

Wenn eine globale Variable fehlt (zum Beispiel von einem Skript im HTML), deklarierst du sie in einer .d.ts-Datei:

// global.d.ts
declare const APP_VERSION: string;
interface Window { analytics?: { track(name: string): void } }

Merke

  • Für den Browser braucht die tsconfig.json die Bibliothek DOM
  • querySelector kann null liefern: prüfen oder mit Hilfsfunktion absichern
  • Ereignisse sind typisiert: MouseEvent, KeyboardEvent, SubmitEvent
  • Node.js: @types/node installieren; node:-Importe nutzen
  • .d.ts-Dateien ergänzen fehlende globale Typen

Übungsaufgabe

Schreibe eine typisierte Hilfsfunktion waehle<T extends Element>(selektor), die einen Fehler wirft, wenn das Element fehlt, und benutze sie in einem kleinen Formular.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Asynchroner Code und Laufzeitprüfung

Weiter: Typen für Bibliotheken und Deklarationsdateien

Alle Kapitel: TypeScript im Überblick