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. This is 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, and your progress syncs across the web and the CoddyKit app. The TypeScript Academy course includes 3 lessons in total.
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.
Learn TypeScript with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 101
- Lessons
- 352
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. 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. The TypeScript Academy course includes 3 lessons in total.
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, so you can start here or from the beginning and move at your own pace. This is lesson 2 of 3.
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
- lib DOM types & querySelector (strict null checks)
- Event types, custom events; narrowing HTMLElement subtypes
- Working with FormData, URL, URLSearchParams