0Pricing
TypeScript Academy · Lesson

Event types, custom events; narrowing HTMLElement subtypes

Handle DOM events with correct types, create CustomEvent payloads, and narrow HTMLElement subtypes safely.

Event types, custom events; narrowing HTMLElement subtypes is a free TypeScript Academy lesson on CoddyKit — lesson 2 of 3. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 3 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Intro

Goal: Add typed event listeners, narrow elements safely, and emit CustomEvent with payloads.

  • Event types (MouseEvent, KeyboardEvent, InputEvent)
  • Narrow target/currentTarget with instanceof
  • CustomEvent detail payloads

Typed listeners

Listener signatures are typed by event name: click → MouseEvent, keydown → KeyboardEvent. Add explicit annotations for clarity.

const btn = document.querySelector("#btn");
if (btn) {
  btn.addEventListener("click", (ev: MouseEvent) => {
    console.log("x=", ev.clientX, "y=", ev.clientY);
  });
}

window.addEventListener("keydown", (ev: KeyboardEvent) => {
  console.log("key=", ev.key);
});

target vs currentTarget

target is the original source and can be many types; currentTarget is the listener's receiver. Narrow with instanceof before using element APIs.

document.addEventListener("input", (ev: InputEvent) => {
  const t = ev.target;
  const c = ev.currentTarget; // here: Document
  if (t instanceof HTMLInputElement) {
    console.log("value=", t.value);
  }
});

CustomEvent payload

CustomEvent<T> carries a typed detail payload. Dispatch and handle it with matching generic parameter.

type CounterDetail = { delta: number };

const inc = new CustomEvent<CounterDetail>("counter:change", {
  detail: { delta: 1 }
});

document.dispatchEvent(inc);

document.addEventListener("counter:change", (ev: CustomEvent<CounterDetail>) => {
  console.log("delta=", ev.detail.delta);
});

Subtype narrowing

Use instanceof to refine to specific HTML element classes (e.g., HTMLButtonElement, HTMLAnchorElement).

document.addEventListener("click", (ev: MouseEvent) => {
  const el = ev.target;
  if (el instanceof HTMLButtonElement) {
    el.disabled = true; // safe: HTMLButtonElement API
  } else if (el instanceof HTMLAnchorElement) {
    console.log("href=", el.href);
  }
});

Delegation + guard

Delegation: Listen high up (document), then find a matching element and narrow it before accessing APIs.

document.addEventListener("click", (ev: MouseEvent) => {
  const el = ev.target as Element | null;
  if (!el) return;
  const btn = el.closest("button.btn-primary");
  if (btn instanceof HTMLButtonElement) {
    console.log("delegated click on:", btn.textContent);
  }
});

Narrowing check

Quick check: What is the safest way to access element-specific APIs in an event handler?

Recap

Recap: Event names imply event types. Use instanceof to narrow target/currentTarget, and carry data in CustomEvent<T> detail.

Frequently asked questions

Is the “Event types, custom events; narrowing HTMLElement subtypes” lesson free?

Yes — the full text of “Event types, custom events; narrowing HTMLElement subtypes” is free to read here on the web, and the TypeScript Academy course includes 3 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.

What will I learn in “Event types, custom events; narrowing HTMLElement subtypes”?

Handle DOM events with correct types, create CustomEvent payloads, and narrow HTMLElement subtypes safely. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start TypeScript Academy?

No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 3, so you can start here or from the beginning and move at your own pace.

How long does the “Event types, custom events; narrowing HTMLElement subtypes” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this TypeScript Academy lesson?

Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. lib DOM types & querySelector (strict null checks)
  2. Event types, custom events; narrowing HTMLElement subtypes
  3. Working with FormData, URL, URLSearchParams
← Back to TypeScript Academy