-
Notifications
You must be signed in to change notification settings - Fork 3k
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
fix(fromEvent): infer from Node.js EventEmitter with types #6669
Conversation
…eral from Node.js EventEmitter
After the latest commit f25a174 it turns out the code has a bug:
This problem is because "overload resolution in conditional types is not supported yet" in current versions of TypeScript (said @RyanCavanaugh, from here) However, there have workarounds that can make it work, only need we write more codes (luckily they will be all typing definitions so there will be no runtime overhead added). This bug also exists in the |
After two days of hard work, I finally made it! I want to use I feel strange that why RxJS lack this support, and I talked with @andywer (creator of typed-emitter) and @devanshj (creator of rxjs-from-emitter) for some solutions with their great NPM modules, but still not a very easy-to-understand & out-of-the-box solution. At the beginning of the last week, I feel it will not too hard to add support to the RxJS itself, and I finally realized that it's not easy after I have dived deep into it. The TypeScript system does not support this because of the design limitation, which turns my work into hard mode and I start to understand that why the RxJS does not support it for the past years. (I guess it's the same reason) Futurnatelly, there's workarounds, like get return type when @benlesh Could you please review this PR and let me know what do you think? I'd like to keep improving it if you have any suggestions, and I'm looking forward to seeing this PR being merged and we can use the auto-infer Thanks for reading, cheers! |
spec/observables/fromEvent-spec.ts
Outdated
* Huan(202111): Correct typing inference for Node.js EventEmitter as `number` | ||
* @see https://github.com/ReactiveX/rxjs/pull/6669 | ||
*/ | ||
it('should successful inference the first argument from the listener of Node.js EventEmitter', (done) => { |
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.
These sorts of tests we do with dtslint
. They're under a different directory and are run with npm run dtslint
.
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.
Moved to dtslint
AnyToUnknown, | ||
} from '../../src/internal/util/NodeEventEmitterDataType'; | ||
|
||
describe('NodeEventEmitterDataType smoke testing', () => { |
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.
Same as my other comment. These should be dtslint
tests. :)
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.
Moved to dtslint
@@ -0,0 +1,236 @@ | |||
/** | |||
* Issue #6669 - fix(fromEvent): infer from Node.js EventEmitter with types |
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'm not sure how these comments will affect our documentation system. Probably should just stick regular doc comments as seen elsewhere in the code base.
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 will remove them
Removed.
/** | ||
* Node.js EventEmitter Add/Remove Listener interface | ||
*/ | ||
interface L<N, D> { |
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 would be great if we used more descriptive names here.
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 agree that the descriptive name will be more readable, and at first, I was using the descriptive name.
However, the reason that I finally use the short name (L
for Listener, N
for Name, and D
for Data) is that the below code will have lots of repeated those type names:
For example:
type EventNameDataPair9<AddRemoveListener> = AddRemoveListener extends L9<
infer N1,
infer N2,
infer N3,
infer N4,
infer N5,
infer N6,
infer N7,
infer N8,
infer N9,
infer D1,
infer D2,
infer D3,
infer D4,
infer D5,
infer D6,
infer D7,
infer D8,
infer D9
>
? [N1, D1] | [N2, D2] | [N3, D3] | [N4, D4] | [N5, D5] | [N6, D6] | [N7, D7] | [N8, D8] | [N9, D9]
: never;
The above code will be very long and I feel the short version of the name is more readable, so I'd like to suggest that we can keep this short name because they are very to be understood:
L
- ListenerN
- NameD
- Data
On the other hand, I'm OK with using a more descriptive(long) name if you think the long version is better.
Please let me know your final decision and I'll follow it.
Overall, this is a very interesting addition. I'll flag it for review by the core team, because I would really like @cartant's input here. I know this area is something we wanted to improve. There are a few things you'll need to adjust, @huan, and I think we're likely to bikeshed names and documentation a little bit, but overall, I really like the initiative here. |
Hi @benlesh , It's great to know that you like it! I have followed your comments and fixed most of them, and will continue dealing with the "descriptive name" once get your new feedback. Have a great day! |
Core Team: We feel this may add too much complexity to our already complex typings. This might work as a user-land package that adds type definitions though. |
Thank you for all the effort, @huan! Hopefully no hard feelings! |
No problem, @benlesh , I have learned a lot by building this PR, and understand the decision of the core team. I'd like to publish this feature to a user-land package, could you please give me some advice for it? For example:
|
Description:
Using
fromEvent
with a Node.js EventEmitter will get aObserverable<unknown>
, as the below TS code shows:I'll add a unit test first, to demonstrate this situation,
then try to add some code to fix & improve its compatibility.
Related issue (if exists):
util.promisify
an function with overloading definations microsoft/TypeScript#26048The fix for this unit test:
Before the code fix, the unit test shows:
After the code fix
It should be able to turn green, with the correct typing inference:
Observable<number>
instead ofObservable<unknown>