Skip to content

Cannot extend types on inheriting classes  #243

@antoniom

Description

@antoniom

I have a class that extends EventEmitter. I have added type support on that event emitter and everything works pretty well:

// BaseClass.ts
import EventEmitter from "eventemitter3";

type EventTypes = {
  foo: () => void;
  bar: (error: Error) => void;
};

export default class extends EventEmitter<EventTypes> {
  constructor() {
    super();
    this.emit("foo");
    this.emit("bar", new Error("bar"));
  }
}

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

// BaseClass.ts
import EventEmitter from "eventemitter3";

type EventTypes = {
  foo: () => void;
  bar: (error: Error) => void;
};

export default class<T extends object> extends EventEmitter<EventTypes & T> {
  constructor() {
    super();
    this.emit("foo");
    this.emit("bar", new Error("bar"));
  }
}

and my ChildClass:

// ChildClass.ts
import BaseClass from "./BaseClass";

type ExtraTypes = {
  baz: () => void;
};

export default class extends BaseClass<ExtraTypes> {
  constructor() {
    super();
    this.emit("foo");
    this.emit("bar", new Error("bar"));
    this.emit("baz");
  }
}

While ChildClass is OK, TS compiler starts complaining on BaseClass on every emit generating the following error:

Argument of type '"foo"' is not assignable to parameter of type 'EventNames<EventTypes & T>'

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions