-
Notifications
You must be signed in to change notification settings - Fork 226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot extend types on inheriting classes #243
Comments
Hey @antoniom, I’m having the same issue. Did you find a solution? |
@alexryd I actually ended up implementing my own on* callbacks and using different instances of EventEmitter on each class. It turned out that I never had to emit a parent event from my child class. // BaseClass.ts
import EventEmitter from "eventemitter3";
type EventTypes = {
foo: () => void;
bar: (error: Error) => void;
};
export default class {
private _ee: EventEmitter<EventTypes> = new EventEmitter();
constructor() {
super();
this.emit("foo");
this.emit("bar", new Error("bar"));
}
public onFoo = (func: EventTypes["foo"]) => this._ee.on("foo", func)
public onBar = (func: EventTypes["foo"]) => this._ee.on("bar", func)
}
// ChildClass.ts
import BaseClass from "./BaseClass";
type ExtraTypes = {
baz: () => void;
};
export default class extends BaseClass {
private _ee: EventEmitter<ExtraTypes> = new EventEmitter();
constructor() {
super();
}
} |
I'm in exactly the same position. Not sure if it's a limitation of TypeScript or of this library. |
Same here, still trying some workarounds |
I wish I had discovered this issue a while ago, but then I may not have discovered my final (for-now) resolution. The 2 remaining issues I have:
Both issues are detailed here along with my final working solution. Hopefully it helps! Cheers! From stackoverflow less code comments: type TRaceEvents = {
raceUpdate: (race: IRace | null) => void;
}
interface IRaceManager extends EventEmitter {
race: IRace;
start() => void;
}
class StandardRaceManager extends EventEmitter<TRaceEvents> implements IRaceManager {
constructor(public race: IRace) { super(); }
start() {
this.race.status = "Running";
this.emit("raceUpdate", this.race as any); // `as any` fixes squiggly but isn't needed for compile or runtime
}
let race = {_id: 1, status: "taxiing"} as IRace;
const standardRace: IRaceManager = new StandardRaceManager(race);
standardRace.on("raceUpdate", race => console.log(race));
standardRace.start();
standardRace.emit("raceUpdate", standardRace.race);
// Emits are restricted to TRaceEvents
race = {_id: 2, status: "taxiing"} as IRace;
class AnotherRaceManager extends StandardRaceManager {}
const anotherRace: IRaceManager = new AnotherRaceManager(race);
anotherRace.start();
anotherRace.emit("raceUpdate", anotherRace.race); // `as any` is not required here, for some reason. |
Anyone found a solution to this? |
This worked for me: // BaseClass.ts
import EventEmitter from "eventemitter3";
export interface EventTypes {
foo: () => void;
bar: (error: Error) => void;
}
export class BaseClass<T extends EventTypes> extends EventEmitter<EventTypes | T> {
constructor() {
super();
this.emit("foo");
this.emit("bar", new Error("bar"));
}
} // ChildClass.ts
import { BaseClass, EventTypes } from "./BaseClass";
interface ExtraTypes extends EventTypes {
baz: () => void;
}
export class ChildClass extends BaseClass<ExtraTypes> {
constructor() {
super();
this.emit("foo");
this.emit("bar", new Error("bar"));
this.emit("baz");
}
} Summary of changes:
|
Confirming that @pauloddr 's solution works perfectly.
You can also do this with types, using the import EventEmitter from "eventemitter3";
export class BaseAdapter<T extends BaseEvents> extends EventEmitter<BaseEvents | T> {
constructor() {
super()
this.emit('base-event', { foo: 'bar' })
}
}
export class CustomAdapter extends BaseAdapter<CustomEvents> {
constructor() {
super()
this.emit('base-event', { foo: 'bar' })
this.emit('custom-event', { baz: 42 })
}
}
type BaseEvents = {
'base-event': (payload: { foo: string }) => void
}
type CustomEvents = BaseEvents & {
'custom-event': (payload: { baz: number }) => void
}` |
This solution works.! For now I have to make every child class at each level a generic class. |
I have a class that extends EventEmitter. I have added type support on that event emitter and everything works pretty well:
Problems start when I try to extend that class, and the child class needs to emit some extra events. To support that type of functionality I had to add generics on my previous class
and my ChildClass:
While ChildClass is OK, TS compiler starts complaining on BaseClass on every emit generating the following error:
I am not sure if this is a weakness in TS, eventemitter3's type system or something wrong in my code but how can I bypass the problem?
Codesanbox link: https://codesandbox.io/s/pedantic-drake-d73tv
The text was updated successfully, but these errors were encountered: