Reputation: 45454
I have code like this:
import * as events from 'events' // Node.js events module
// my own version of EventEmitter with better typing
interface IEventEmitter<EventTypes> { /* ... */ }
// eslint-disable-next-line typescript/explicit-function-return-type
export function EventEmitter<EventTypes>() {
// merge the IEventEmitter interface and EventEmitter as IEventEmitter
// implementation into one.
// XXX Is there a better way?
return class NewEventEmitter
extends ((events.EventEmitter as unknown) as IEventEmitter<EventTypes>)
implements IEventEmitter<EventTypes> {}
}
As you can see I disabled an eslint rule so that it doesn't complain that I haven't specified the return type, and I let the return type be inferred.
But, how would I write that return type?
EDIT: Here's a playground example that shows @KarolMajewski's answer isn't working for me. It says Cannot find name 'NewEventEmitter'. Did you mean 'NodeEventEmitter'?
.
EDIT 2: @KarolMajewski's answer does indeed work. For it to work, the class has to be assigned to a local variable. Here's the playground example.
Upvotes: 2
Views: 1773
Reputation: 25790
Between writing explicit return types and letting TypeScript infer their type, there is a third way:
import * as events from 'events';
interface IEventEmitter<EventTypes> { /* ... */ }
export function EventEmitter<EventTypes>(): typeof MyClass {
const MyClass = class extends events.EventEmitter implements IEventEmitter<EventTypes> {};
return MyClass;
}
Although it's a bit of a trick, and it requires what's called an unnecessary local variable. In this case, this variable (MyClass
) is used only to read type from.
Upvotes: 1
Reputation: 2396
Declare the return type to be IEventEmitter<EventTypes>
function makeEventEmitterClass<EventTypes>(): IEventEmitter<EventTypes> {
// merge the IEventEmitter interface and EventEmitter as IEventEmitter
// implementation into one.
return class NewEventEmitter
extends ((NodeEventEmitter as unknown) as IEventEmitter<EventTypes>)
implements IEventEmitter<EventTypes> {}
}
Upvotes: 0