andywer / typed-emitter

🔩 Type-safe event emitter interface for TypeScript
MIT License
268 stars 24 forks source link

Property __events introduced for FromEvent breaks EventEmitter inheritance #29

Closed evanshortiss closed 2 years ago

evanshortiss commented 2 years ago

Attempting to create a class that extends EventEmitter per the README fails:. For example:

export class Foo extends (EventEmitter as new () => TypedEmitter<MyEvents>) {}

The error reported is:

Property '__events' is missing in type 'EventEmitter' but required in type 'TypedEventEmitter<MyEvents>'

This appears to happen due to these lines to support FromEvent. Removing those fixes the issue.

Casting to unknown first will resolve the issue, i.e class Foo extends EventEmitter as unknown as new () => TypedEmitter<MyEvents> is working fine.

Should the documentation be updated?

andywer commented 2 years ago

Thanks for reporting, @evanshortiss!

No, we shouldn't update the readme, this is definitely a bug we need to fix 😕 Maybe a quick fix could be to declare __events as an optional property.

andywer commented 2 years ago

@huan Thoughts?

huan commented 2 years ago

@andywer I have been facing the same issue and I'm using the same workaround as @evanshortiss did:

https://github.com/wechaty/wechaty/blob/6db8f6a62cad0d6e2b7e139927df3d21ebdbead9/src/schemas/wechaty-events.ts#L221-L223

I have thought about this for some time but have no better ideas yet.

andywer commented 2 years ago

@huan What about this?

Maybe a quick fix could be to declare __events as an optional property.

evanshortiss commented 2 years ago

Maybe a quick fix could be to declare __events as an optional property.

This works for me. I guess it might be a bit awkward for devs using FromEvent? Another option might be to create a separate interface for the FromEvent typing? Something like this maybe?

export interface TypedFromEmitter extends TypedEventEmitter { __events: Events }
huan commented 2 years ago

I think creating a separate interface might be clearer for the solution, and it will not introduce any unexpected behavior for the user who does not need this feature.