Skip to content

Instantly share code, notes, and snippets.

@ewmb7701
Created January 31, 2026 10:42
Show Gist options
  • Select an option

  • Save ewmb7701/eb56ba01f9e122e2fe28ca52703bd797 to your computer and use it in GitHub Desktop.

Select an option

Save ewmb7701/eb56ba01f9e122e2fe28ca52703bd797 to your computer and use it in GitHub Desktop.
type HTMLElementAttributes<THTMLElement extends keyof HTMLElementTagNameMap> = {
[K in keyof HTMLElementTagNameMap[THTMLElement]]?: HTMLElementTagNameMap[THTMLElement][K] extends DOMTokenList
? string | HTMLElementTagNameMap[THTMLElement][K]
: HTMLElementTagNameMap[THTMLElement][K];
};
/**
* Append a single Node or string as a text node to a parent element.
*/
function appendChild(parent: HTMLElement, child: Node | string) {
if (typeof child === "string") {
parent.appendChild(document.createTextNode(child));
} else {
parent.appendChild(child);
}
}
/**
* Append a child or array of children.
*/
function appendChildOrChildren(
parent: HTMLElement,
children: Node | string | Array<Node | string>,
) {
if (Array.isArray(children)) {
for (const child of children) appendChild(parent, child);
} else {
appendChild(parent, children);
}
}
/**
* Create an HTML element with typed props and children.
*
* @template T
* @param tag - HTML tag name
* @param attributes - Attributes or properties
* @param children - Child nodes or text
*/
function h<T extends keyof HTMLElementTagNameMap>(
tag: T,
attributes?: HTMLElementAttributes<T>,
children?: Node | string | Array<Node | string>,
): HTMLElementTagNameMap[T] {
const element = document.createElement(tag) as HTMLElementTagNameMap[T];
if (attributes) {
for (const [key, value] of Object.entries(attributes)) {
if (key in element) {
// @ts-ignore
element[key] = value;
} else {
element.setAttribute(key, String(value));
}
}
}
if (children) {
appendChildOrChildren(element, children);
}
return element;
}
export { h, h as default, type HTMLElementAttributes };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment