How to change types of a class that extends another class with an interface

Viewed 113

I have a class Sprite that extends from another class that comes from a library, its name is PIXI.Sprite, it extends from the PIXI.utils.EventEmitter class but the names of the events, etc are not strictly typed, so I've created my own implementation of this class via a custom class EventEmitter extending PIXI.utils.EventEmitter that waits for a record of eventName: [...types] in a Generic argument.

But since we can't extend from two classes, and the on, once, emits... methods are not well-typed, I need a way to change their types, I tried via an interface that extends my EventEmitter class, but it doesn't work.

Here are my classes :

import * as PIXI from 'pixi.js';

export type EventList = Record<string, any[]>;

export class EventEmitter<Events extends EventList> extends PIXI.utils.EventEmitter {
    public emit<K extends (keyof Events) & string>(event: K, ...args: Events[K]): boolean {
        return super.emit(event, ...args);
    }

    public on<K extends (keyof Events) & string>(event: K, fn: (...params: Events[K]) => void, context?: any): this {
        return super.on(event, fn as (...args: any[]) => void, context);
    }

    public once<K extends (keyof Events) & string>(event: K, fn: (...params: Events[K]) => void, context?: any): this {
        return super.once(event, fn as (...args: any[]) => void, context);
    }
}

export interface IEventEmitter<Events extends EventList> extends EventEmitter {
    emit<K extends (keyof Events) & string>(event: K, ...args: Events[K]): boolean;
    on<K extends (keyof Events) & string>(event: K, fn: (...params: Events[K]) => void, context?: any): this;
    once<K extends (keyof Events) & string>(event: K, fn: (...params: Events[K]) => void, context?: any): this

}

export type SpriteEvents = {
    click: [event: PIXI.InteractionEvent];
}


export class Sprite extends PIXI.Sprite implents IEventEmitter<SpriteEvents> {
    // some code.
}

const a = new Sprite();

When I type a.on(', it should only suggest me click but no, when I hover it, it says that the method has the types of the PIXI.Sprite.prototype.on method, not the one from the interface.

How can I have my methods properly typed without copying the code from my EventEmitter class (which indeed corrects the problem but is dirty) ?

0 Answers
Related