fix(fromEvent): infer from Node.js EventEmitter with types#6669
fix(fromEvent): infer from Node.js EventEmitter with types#6669huan wants to merge 21 commits intoReactiveX:masterfrom
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.
These sorts of tests we do with dtslint. They're under a different directory and are run with npm run dtslint.
| AnyToUnknown, | ||
| } from '../../src/internal/util/NodeEventEmitterDataType'; | ||
|
|
||
| describe('NodeEventEmitterDataType smoke testing', () => { |
There was a problem hiding this comment.
Same as my other comment. These should be dtslint tests. :)
| @@ -0,0 +1,236 @@ | |||
| /** | |||
| * Issue #6669 - fix(fromEvent): infer from Node.js EventEmitter with types | |||
There was a problem hiding this comment.
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.
I will remove them
Removed.
| /** | ||
| * Node.js EventEmitter Add/Remove Listener interface | ||
| */ | ||
| interface L<N, D> { |
There was a problem hiding this comment.
It would be great if we used more descriptive names here.
There was a problem hiding this comment.
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
fromEventwith 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.promisifyan 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>