Skip to content

allow abstract interfaces in class definitions #5194

Closed
@drarmstr

Description

@drarmstr

TypeScript 1.6 added support for abstract class classes which allow a class to have optional method definitions. I have a different situation where I am defining a TypeScript class. However, this TypeScript class is actually instantiated by some other 3rd party library which manually adds additional methods outside of TypeScript's knowledge. Additionally, this object created is also an HTMLElement. This situation would also come up if anyone manually adds a method to an object instance.

The problem is that in my class methods the this object is only known to have the methods I defined in my class. I could explicitly cast this as the base type when I need to use the 3rd party method or HTMLElement method like (<BaseInterface><any>this).base_method(), but this is ugly and not clear to users what interfaces are available, particularly further down the inheritance chain. Currently, the approach I am using to get proper type checking is to add an extra property just for casting:

class MyComponent {
    get base(): BaseInterface { return <BaseInterface><any>this; }
    get el(): HTMLElement { return <HTMLElement><any>this; }
}

This adds runtime overhead and is a bit ugly, as i have to reference base methods like instance.base.base_method(). Instead, I would like to do something like:

class MyComponent implements BaseInterface {
}

However, this doesn't work because I get an error that MyComponent doesn't implement base_method.

So, I am proposing to allow extends with multiple interfaces in addition to or instead of a single class:

class MyComponent extends BaseInterface, HTMLElement {
}

Or, if you want to be more explicit that we are trying to model something outside the normal TypeScript class hierarchy that is allowed by JavaScript, then perhaps requiring the user to specify that this is an abstract interface:

class MyComponent implements abstract BaseInterface, abstract HTMLElement {
}

The end result is that this would end up being considered an "intersection" type of MyComponent, BaseInterface, and HTMLElement.

Metadata

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions