TypeScript knows that globalThis.document.createElement('img') returns a type of HTMLImageElement based on the string 'img' being passed into the function.
const elem1 = globalThis.document.createElement('img'); //type: HTMLImageElement
console.log(elem1.constructor.name); //'HTMLImageElement'
How would I capture that return type to be used in a wrapper function?
For example, what would the TypeScript declaration be for the createElem function below so that the tag parameter determines the correct return type?
const createElem = (tag: keyof HTMLElementTagNameMap) => {
const elem = globalThis.document.createElement(tag);
elem.dataset.created = String(Date.now());
return elem;
};
const elem2 = createElem('img'); //type: HTMLElement | ...68 more...
console.log(elem2.constructor.name); //'HTMLImageElement'
A tag value of ’img’ should result in a HTMLImageElement type. A tag value of ’p’ should result in a HTMLParagraphElement type and so on.
If you check the official type definition of
createElementyou will see:Let's apply the same logic to your function:
Testing:
Link to Playground
Additionally,
createElementsupports passing any other strings as well, which is achieved using function overloading:You can do the same thing for your function if you need that. Note that the order of overloads is important. The most defined one should come first. Which is
keyof HTMLElementTagNameMapin your case. The reason is typescript looks through the overloads from top to bottom and if you put the overload withstringfirst then it would reach thekeyof HTMLElementTagNameMap.