-
Notifications
You must be signed in to change notification settings - Fork 226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TypeScript Bindings #72
Conversation
* Return the listeners registered for a given event. | ||
*/ | ||
listeners(event: string | symbol): Array<ListenerFn>; | ||
listeners(event: string | symbol, exists: boolean): Array<ListenerFn> | boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should exists
be exists?
? It is optional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In TypeScript definitions, you can provide overloaded typings for the same method.
One implementation only takes event
and always returns an array of listeners. The overload takes both parameters and either returns an array of listeners or a boolean, depending on the value of exists
.
It is a best practice to put the most specific overload first, so I did swap the order of these in 365bef6.
/** | ||
* Remove all listeners, or those of the specified event. | ||
*/ | ||
removeAllListeners(event: string | symbol): EventEmitter; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
event
is optional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔧 a711d93
type ListenerFn = (...args: Array<any>) => void; | ||
|
||
/** | ||
* Minimal `EventEmitter` interface that is molded against the Node.js |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please "fix" the indentation of these comments? Indent the second line and the following with 1 space.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoa.. good catch. That's weird. 🔧 3e5f97a
Looks good but my experience with TypeScript is close to zero so if another pair of eyes could review this it would be great. |
I believe module UPD. Nevermind, didn't notice related changes in #71 |
@Stubb0rn so LGTY? |
* `EventEmitter` interface. | ||
*/ | ||
export class EventEmitter { | ||
prefix: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This property should be static
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, also the correct name is prefixed
and can be either a string or a boolean (false
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔧 9c00931
/** | ||
* Add a listener for a given event. | ||
*/ | ||
on(event: string | symbol, fn: ListenerFn, context?: any): EventEmitter; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of EventEmitter
it is better to use this
as return type of methods that support fluent interface. This will enable access to own methods of classes that extend EventEmitter
:
class TestEmitter extends EventEmitter {
...
test() {}
}
new TestEmitter().on().test();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔧 780c427
@@ -0,0 +1,50 @@ | |||
export as namespace EventEmitter; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Current definition of exports might work well with ES6 syntax but not so well with standard TypeScript import syntax:
import EventEmitter = require('eventemitter3');
new EventEmitter();
This code will not compile with current export definition and this syntax could be used by many users of this library that use it with TypeScript (especially in Node environment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's true that we cannot support both the import =
and the ES6-style imports with the type definitions. We need to choose one. I put a bit of consideration into this when I wrote the defs.
The problem with import =
is that if you use it anywhere in your code, you cannot compile into ES6 modules. I need to enable that setting, which was my motivation for this PR as well as #71.
Any users who are currently using this repository with TypeScript either wrote their own definitions or are using the (old) ones from DefinitelyTyped. I wonder what happens if this repository had these definitions included and the user had the DT definitions installed as well. That may allow legacy code to continue working while new projects can use the ES6 import syntax.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that shipping typings that use ES6-style imports will break anyone's existing code.
If exists ambient external module named X {
return the ambient external module
}
else if X begins with './' or '../' or it is rooted path {
try LOAD_AS_FILE(Y + X, loadOnlyDts=false)
try LOAD_AS_DIRECTORY(Y + X, loadOnlyDts=false)
}
else {
LOAD_NODE_MODULES(X, dirname(Y))
}
THROW "not found"
So if a user already has .d.ts
files installed for eventemitter3, the definitions in this node module would not be used. This is consistent with what I tested locally.
all looks good to me :D |
This pull request adds TypeScript bindings for the public interface of eventemitter3 (See issue #67).
The typings were written in the UMD style - that is, they will work correctly for scripts using module loaders as well as for scripts that reference
EventEmitter
as a global.