From 6e404eac6b889129dbeb46c4ce2205dffdb2d5a3 Mon Sep 17 00:00:00 2001 From: OFF0 Date: Sun, 5 Mar 2023 20:45:20 +0100 Subject: [PATCH] refactor: type element attributes use attributes of html element type. so that the following example is correctly typed: elem('input', { className: 'foo', hidden: false, onclick: () => alert('hi'), tabIndex: 1, valueAsNumber: 1, }); but this fails as foo is no valid attribute on div element: elem('div', {foo: 'bar'}); --- src/utils/dom.ts | 54 +++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/src/utils/dom.ts b/src/utils/dom.ts index a697702..7b3c41b 100644 --- a/src/utils/dom.ts +++ b/src/utils/dom.ts @@ -1,11 +1,11 @@ -type Attributes = { - [key: string]: string | number; -} & { - data?: { +type DataAttributes = { + data: { [key: string]: string | number; } }; +type Attributes = Partial; + /** * example usage: * @@ -15,31 +15,43 @@ type Attributes = { * * @param {string} name * @param {HTMLElement.prototype} props - * @param {Array} children + * @param {Array | string | number} children * @return HTMLElement */ export const elem = ( name: Extract, - attrs: Attributes = {}, // TODO optional - children: Array | string = [], // TODO optional + attrs?: Attributes, + children?: Array | string | number, ): HTMLElementTagNameMap[Name] => { - const {data, ...props} = attrs; const el = document.createElement(name); - Object.assign(el, props); - if (Array.isArray(children)) { - el.append(...children); - } else { - const childType = typeof children; - if (childType === 'number' || childType === 'string') { - el.append(children); - } else { - console.error('call me'); + if (attrs) { + const {data, ...props} = attrs; + Object.assign(el, props); + if (data) { + Object.entries(data).forEach(([key, value]) => { + el.dataset[key] = value as string; + }); } } - if (data) { - Object.entries(data).forEach(([key, value]) => { - el.dataset[key] = value as string; - }); + if (children != null) { + if (Array.isArray(children)) { + el.append(...children); + } else { + switch (typeof children) { + case 'number': + el.append(`${children}`); + break; + case 'string': + el.append(children); + break; + default: + if (children instanceof Element) { + el.append(children); + break; + } + console.error(`expected element, string or number but got ${typeof children}`, children); + } + } } return el; };