Reputation: 6053
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?
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());
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
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