GGistDev

DOM and Lib Types in TypeScript

TypeScript ships rich ambient type definitions for web APIs via lib.dom.d.ts and other libraries.

Querying the DOM

const el = document.getElementById("app");           // HTMLElement | null
const btn = document.querySelector<HTMLButtonElement>("button.primary");
if (btn) btn.disabled = true;

const all = document.querySelectorAll<HTMLElement>(".item"); // NodeListOf<HTMLElement>
all.forEach(node => node.classList.add("active"));

Prefer generic overloads on querySelector/All to specify element types.

Events and listeners

const input = document.querySelector<HTMLInputElement>("#name");
input?.addEventListener("input", (ev) => {
  const t = ev.currentTarget as HTMLInputElement; // or use generic listener
  console.log(t.value);
});

function onClick(el: HTMLButtonElement, cb: (this: HTMLButtonElement, ev: MouseEvent) => void) {
  el.addEventListener("click", cb);
}

Use the this parameter for precise callbacks.

Fetch and Response types

async function getJson<T>(url: string): Promise<T> {
  const res = await fetch(url);
  if (!res.ok) throw new Error("bad status");
  return res.json() as Promise<T>;
}

Timers and animation

const id = setTimeout(() => {}, 100);
clearTimeout(id);

requestAnimationFrame((ts: number) => { /* ... */ });

Note: In Node, timers types differ; rely on @types/node or DOM lib depending on target.

lib.d.ts and target libs

Control available global types via tsconfig.json lib option.

{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["ES2020", "DOM", "DOM.Iterable"]
  }
}

Add DOM.Iterable for for..of on NodeLists.

Strictness and nullability

DOM APIs often return T | null. Narrow before use or use non-null assertion ! sparingly.

const el2 = document.getElementById("app")!; // be sure it's present

Prefer explicit guards to avoid runtime errors.

Summary

  • Use generic querySelector overloads to type elements
  • Handle null from DOM APIs; leverage lib settings to include required web APIs