'Typescript - Is it possible to reference interfaces from extended interface?

I wanted to add chained functionality to all of the interfaces in HTMLElementTagNameMap. Since there are dozens of them and all of the elements either are HTMLElement or extend it, I thought there should be a way of doing something like this:

interface HTMLElement {
    doSomething<K extends keyof HTMLElementTagNameMap>(anArgument: any): HTMLElementTagNameMap[K]
}

This of course doesn't work, because every interface extending HTMLElement now contains a doSomething method that is expected to return any of the HTMLElementTagNameMap values. Instead, I want for HTMLTableElement.doSomething to return an object of type HTMLTableElement, HTMLDivElement.doSomething to return an object of type HTMLDivElement and so on.

Is such a generalization possible or do I need to 'duplicate' it for every interface?

And if it is possible, how do I do it?



Solution 1:[1]

I think a return type of this is what you want.

Here's a demo:

interface HTMLElement {
    foo(): this;
}

const a = document.createElement("a");

// ...

const aFoo = a.foo();
//    ^^^^
// HTMLAnchorElement

// ...

In the demo, you can hover over the variable that has the result of calling foo assigned to it and see the type is the interface for the respective HTML element.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Wing