Bonjour,

Je rencontre un petit problème avec mon code TypeScript.

Ce que je fais

Je développe une classe (Audio) en TypeScript qui doit contenir une gestion d'émetteurs typés d'évènements.
Pour cela, je défini un type (AudioEvents) qui à chaque nom d'évènement associe un tableau qui contient les types des arguments à passer en paramètre du listener. Je défini ensuite les méthodes "emit()" et "on()" pour gérer les listeners de ces évènements.

type AudioEvents = {
    start: [string],
    stop: []
};

export class Audio {
    private _listeners: {
        [E in keyof AudioEvents]: Array<(...args: AudioEvents[E]) => void>
    } = {
        "start": [],
        "stop": []
    };

    on<E extends keyof AudioEvents>(event: E, listener: (...args: AudioEvents[E]) => void) {
        this._listeners[event].push(listener);
    }

    private emit<E extends keyof AudioEvents>(event: E, ...args: AudioEvents[E]) {
        this._listeners[event].forEach(listener => {
            listener(args);
        });
    }
}

Ce que je veux

Je cherche simplement à résoudre l'erreur générée par ce code.

Ce que j'obtiens

Les appels à ces deux méthodes fonctionnent bien et l'IDE reconnaît parfaitement leur typage. Les appels suivants ne génèrent pas d'erreur et chaque variable est bien typée.

this.emit("stop");
this.emit("start", title);

audio.on("stop", () => {});
audio.on("start", title => {});

En revanche j'obtiens une erreurs à la transpilation, dans la définition de "emit()" :

Argument of type 'AudioEvents[E]' is not assignable to parameter of type 'string'.
  Type '[string] | []' is not assignable to type 'string'.
    Type '[string]' is not assignable to type 'string'.

                listener(args);

Je ne comprends pas pourquoi j'obtiens cette erreur, mais j'imagine qu'elle est dûe à une incompréhension de ma part. Cela dit, je pense que la façon d'intégrer cette gestion d'émetteurs d'évènements peut être bonne quand je regarde la réaction de l'IDE.

En essayant :

    private emit<E extends keyof AudioEvents>(event: E, ...args: AudioEvents[E]) {
        this._listeners[event].forEach(listener => {
            listener(...args);
        });
    }

J'obtiens alors l'erreur :

Expected 1 arguments, but got 0 or more.

                             listener(...args);

                             [E in keyof AudioEvents]: Array<(...args: AudioEvents[E]) => void>
    Arguments for the rest parameter 'args' were not provided.

Avez vous une idée pour résoudre cette erreur ? Merci d'avance.

Aucune réponse