Jake Holzinger
Jake Holzinger

Reputation: 6053

Implicit inheritance

I'm using a library that extends the prototype of my classes. Although not important, in my case the library adds the EventEmitter prototype to my class, then it instantiates the class with an instance of an EventEmitter. I need to register for the events, but I'm having trouble getting this to play nice. The library was created before ES6 style inheritance via the extends keyword was introduced and I cannot change the library, thus I must rely on some kind of implicit inheritance in my classes.

Is it possible to implicitly inherit another type?


Example code

import { EventEmitter } from 'events';
import { inherits } from 'util';

class Foo {
    constructor() {
        // Do something assuming
        // 'this' is an event emitter
    }
}

inherits(Foo, EventEmitter);

Foo.call(new EventEmitter());

What I've tried

Explicit inheritance - expects call to super, the object is already an event emitter, I just want the types tied to my class.

class Foo extends EventEmitter {
    constructor() {
        this.on('event', ...)
    }
}

[ts] Constructors for derived classes must contain a 'super' call.


Casting to EventEmitter before calling those methods.

class Foo {
    constructor() {
        const e = this as EventEmitter;
        e.on('event', ...)
    }
}

[ts] Type 'this' cannot be converted to type 'EventEmitter'. Type 'Foo' is not comparable to type 'EventEmitter'. Property 'addListener' is missing in type 'Foo'.


Casting to any then to EventEmitter works, but it feels like a hack. Requiring a cast everywhere is also not very elegant, I feel there is a more appropriate solution.

class Foo {
    constructor() {
        const e = this as any as EventEmitter;
        e.on('event', ...)
    }
}

Upvotes: 0

Views: 481

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249466

You can use class/interface declaration merging :

declare class EventEmitter{
  on(n:string):void
}
interface Foo extends EventEmitter { }
class Foo  {
    constructor() {
        this.on('event')
    }
}

Upvotes: 1

Related Questions