emoteJAM icon indicating copy to clipboard operation
emoteJAM copied to clipboard

make tag more typesafe

Open rexim opened this issue 4 years ago • 1 comments

introduced in #72

Essentially get rid of the any

rexim avatar Jun 15 '21 13:06 rexim

Tag can extend the HTMLElement interface. Something like:

interface Tag extends HTMLElement {
    att$: (name: string, value: string) => Tag
    onclick$: (callback: (this: GlobalEventHandlers, ev: MouseEvent) => Tag) => Tag
}

A Tag can then be created with:

const result: Tag = Object.assign(document.createElement(name), {
    att$: function(name, value) {
        this.setAttribute(name, value);
        return this;
    } as Tag["att$"],
    onclick$: function(callback) {
        this.onclick = callback;
        return this;
    } as Tag["onclick$"]
});

The Object.assign() stuff might not be as clean as one would like. Another way to assign att$ and onclick$ to result would be:

const result = document.createElement(name);
(result as Tag).att$ = function(name, value) {
    this.setAttribute(name, value);
    return this;
};
(result as Tag).onclick$ = function(callback) {
    this.onclick = callback;
    return this;
};
// ...
return result as Tag;

And when Tag is no longer any we also need to properly cast the "mundane tags" to the appropriate element type:

function input(type: string) {
    return tag("input").att$("type", type) as Tag & HTMLInputElement;
}

weedz avatar Jan 04 '22 13:01 weedz