strict-event-emitter-types
strict-event-emitter-types copied to clipboard
Class support?
I'm trying to use this library to add types to my class that extends from EventEmitter, but I can't find a way to make it work with my example:
import StrictEventEmitter from "strict-event-emitter-types";
import { EventEmitter } from "events";
interface IEvents {
onValueSended: string;
ready: void;
}
// [ts] Class 'MyClass' incorrectly
// implements interface 'IEvents'.
// Property 'onValueSended' is missing [ts] Generic type 'StrictEventEmitter'
// in type 'MyClass'. requires between 2 and 5 type arguments.
// ↓ ↓
class MyClass extends EventEmitter implements StrictEventEmitter<EventEmitter IEvents> {
constructor() {
super();
// Some long work...
this.emit("ready");
}
sendValue() {
this.emit("onValueSended", "Hello!");
}
}
const myClass = new MyClass();
myClass.on("onValueSended", x => x);
myClass.sendValue(); // ← [ts] Property 'sendValue' does not exist on type 'MyClass'.
myClass.on("ready", () => {/* Do stuff... */ });
Also, there is a way to make it work with computed properties? Lets say I want to have an event called something like
interface IEvents {
/^action_.+/: void;
init: number;
}
/* class MyClass etc... */
myClass.on("action_jump", () => {})
myClass.on("action_dance", (x) => {}) //Error, no payload
myClass.on(/^action_.+/, () => {}) //Match all action events
myClass.on("jump_action", () => {}) //Error
myClass.on("action_", () => {}) //Error
myClass.on("init", (x) => {})
I supose this last one is related with https://github.com/Microsoft/TypeScript/issues/6579 and can't be fixed by this library.
@SrZorro I solved it like this:
const VmEventsEmitter: { new (): StrictEventEmitter<EventEmitter, IVmEvents> } = EventEmitter as any; // ugly AF any cast was required b/c i think i had old nodejs typings. That should not be important
export class VM extends VmEventsEmitter {
// ...
}
It's kinda ulgy but it works 😆
@krzkaczor what version of node are you running? I can probably tweak the types so they work for that version.
As that's the only way I've found thus far to teach class methods about the stricter types, I'll add it to the docs!
@bterlson typings are for 10.3.4
"@types/node@^10.3.4":
version "10.3.4"
Thanks!
I added an example of using this with classes (similar to @krzkaczor's solution). I'm not aware of a better way...
I'll leave this open so I remember to dig into the Node 10.3.4 typings.
So, how should it look like if i have IEvents
with generic types?
For example:
interface IEvents<Value> {
onValueSended: Value;
}
class MyClass<Value> extends (EventEmitter as { new(): StrictEventEmitter<EventEmitter, IEvents<Value>> }) {
...
}
It throws error:
Error:(69, 45) TS2562: Base class expressions cannot reference class type parameters.
@sywka https://github.com/ethereum-ts/evm-ts/blob/master/lib/VM.ts#L21
@krzkaczor I understand, but i need exactly generic for IEvents<Value>
which is taken from MyClass<Value>
and apparently this is impossible.
Why not add a helper to do this?
Eg.
function createStrictEventEmitterClass<T>() {
const TypedEmitter: {
new (): StrictEventEmitter<EventEmitter, T>;
} = EventEmitter as any;
return TypedEmitter;
}
export class MyEventEmitter extends createStrictEventEmitterClass<MyEvents>() {
}
I can send a PR if you want this.
@bterlson I would really like to see this added to your library.
Is someone working on this? @esamattis maybe? Or should I create a PR, and how do you want it structered in your Type only library?