frontend-syntax-js-es2024-ts-dom
Installation
SKILL.md
Frontend Syntax : ES2024 + TypeScript DOM
This skill is the operational reference for ES2024 features that matter at the DOM boundary and the TypeScript narrowing patterns that make lib.dom.d.ts ergonomic instead of hostile. It covers ES2024 grouping / deep-clone / promise / iterator surfaces, scheduler.yield() for INP, TypeScript strict-mode flags, instanceof narrowing on event.target, HTMLElementEventMap augmentation, and Import Attributes. The skill does NOT cover React / Vue / Solid / Svelte / Angular hook patterns, bundler config, Node.js APIs, or Web Components lifecycle (see [[frontend-impl-web-components]]).
Quick Reference
Floor rules
- ALWAYS use
structuredClone(x)for deep cloning data that includesDate,Map,Set, typed arrays, or cycles. NEVER useJSON.parse(JSON.stringify(x))for the same task ; it drops types and crashes on cycles. - ALWAYS use
Promise.withResolvers()when the resolver must be called from outside the promise body. NEVER hoistresolve/rejectout of anew Promise(...)executor with aletdeclaration. - ALWAYS group with
Object.groupBy(items, fn)for string / symbol keys,Map.groupBy(items, fn)for arbitrary object keys. NEVER hand-roll areduceaccumulator for the same task. - ALWAYS narrow
event.targetwithinstanceof HTMLInputElement(or the relevant element class) before reading.value,.checked, or.dataset. NEVER useas HTMLInputElement; the cast lies under delegation and programmatic dispatch. - ALWAYS feature-detect
scheduler.yield()with asetTimeout(_, 0)fallback. NEVER assume it is available ; as of 2026-05-19 only Chromium ships it in stable channels. - ALWAYS feature-detect Iterator helpers (
typeof Iterator?.prototype?.map === "function") when targeting non-evergreen mobile WebViews. NEVER ship.map().filter().take(n).toArray()chains without a polyfill or detection. - ALWAYS narrow
nullreturns fromgetElementById,querySelector, andclosestwithif (!el) return;. NEVER use the!non-null assertion ; the runtime still throws when the ID is missing. - ALWAYS use
import x from "./x.json" with { type: "json" }(Import Attributes). NEVER use the deprecatedassert { type: "json" }syntax.