Skip to content
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(publish): fix selector typings #2891

Merged
merged 1 commit into from
Oct 5, 2017
Merged

Conversation

cartant
Copy link
Collaborator

@cartant cartant commented Oct 3, 2017

Description:

Fixes the typings for publish and multicast, so that selectors that change the observable's type are supported.

Adds some typings tests for publish and multicast.

Related issue (if exists): #2889

@rxjs-bot
Copy link

rxjs-bot commented Oct 3, 2017

Messages
📖

CJS: 1347.9KB, global: 747.2KB (gzipped: 140.5KB), min: 145.3KB (gzipped: 30.9KB)

Generated by 🚫 dangerJS

@cartant
Copy link
Collaborator Author

cartant commented Oct 3, 2017

With the changes in this PR, the selector type exported from operator/publish.ts is no longer used (internally). Should it be removed?

@coveralls
Copy link

Coverage Status

Coverage remained the same at 97.466% when pulling 2d58972 on cartant:issue-2889 into c7c337e on ReactiveX:master.

@kwonoj
Copy link
Member

kwonoj commented Oct 4, 2017

I recall @benlesh intentionally brought MonoTypeOperatorFunction 🤔

@@ -20,7 +21,7 @@ export function publish<T>(selector: MonoTypeOperatorFunction<T>): MonoTypeOpera
* @method publish
* @owner Observable
*/
export function publish<T>(selector?: MonoTypeOperatorFunction<T>): MonoTypeOperatorFunction<T> {
export function publish<T, R>(selector?: any): any {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be publish<T, R>(selector?: OperatorFunction<T, R>): OperatorFunction<T, R>

Copy link
Collaborator Author

@cartant cartant Oct 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using OperatorFunction<T, R> instead of any effects this error:

25   return selector ?
            ~~~~~~~~~~
26     multicast(() => new Subject<T>(), selector) :
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27     multicast(new Subject<T>());
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

dist/src/operators/publish.ts(25,10): error TS2322: Type '((source: Observable<T>) => Observable<R>) | ((source: Observable<T>) => Observable<T>)' is not assignable to type '(source: Observable<T>) => Observable<R>'.
  Type '(source: Observable<T>) => Observable<T>' is not assignable to type '(source: Observable<T>) => Observable<R>'.
    Type 'Observable<T>' is not assignable to type 'Observable<R>'.
      Type 'T' is not assignable to type 'R'.

The problem is the returning of multicast(new Subject<T>()). That call sees the return type inferred as OperatorFunction<T, T> - hence the error.

The problem can be fixed by using any here, instead of in the signature:

  return selector ?
    multicast(() => new Subject<T>(), selector) :
    multicast(new Subject<T>()) as any; // <-- here

Would you prefer that?

@benlesh
Copy link
Member

benlesh commented Oct 4, 2017

@kwonoj ... this is mostly right. The problem I encountered at work (now that I'm using RxJS with TypeScript all the time, haha) was Observable.of(1, 2, 3).publish(source => source.map(x + '!')) ... would fail because typings didn't permit it. So you had to hack your way through it.

@benlesh
Copy link
Member

benlesh commented Oct 4, 2017

@cartant if you can try to get this in today I'll try to get it out in the next beta. Because I've had to code around it, and it's annoying. haha

@coveralls
Copy link

Coverage Status

Coverage remained the same at 97.465% when pulling d91d414 on cartant:issue-2889 into 5dbad94 on ReactiveX:master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 97.465% when pulling bc34fff on cartant:issue-2889 into 5dbad94 on ReactiveX:master.

Fixes the typings for publish and multicast, so that selectors that
change the observable's type are supported.

Closes ReactiveX#2889
@cartant
Copy link
Collaborator Author

cartant commented Oct 4, 2017

@benlesh After a couple of iterations - each preceded by a cup of coffee - there are now no anys in the typings.

@coveralls
Copy link

coveralls commented Oct 4, 2017

Coverage Status

Coverage remained the same at 97.466% when pulling 2d58972 on cartant:issue-2889 into c7c337e on ReactiveX:master.

Copy link
Member

@benlesh benlesh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So close

@@ -20,7 +21,7 @@ export function publish<T>(selector: MonoTypeOperatorFunction<T>): MonoTypeOpera
* @method publish
* @owner Observable
*/
export function publish<T>(selector?: MonoTypeOperatorFunction<T>): MonoTypeOperatorFunction<T> {
export function publish<T, R>(selector?: OperatorFunction<T, R>): MonoTypeOperatorFunction<T> | OperatorFunction<T, R> {
return selector ?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can go with just OperatorFunction<T, R> as the return type.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. You can't. That will effect the error I mentioned in response to your initial change request.

Copy link
Collaborator Author

@cartant cartant Oct 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a necessity. I don't see it as a problem, as TypeScript uses only the overload signatures when matching methods calls. It won't match calls against the implementation signature - which is why I have the habit of whacking implementation signatures with the any hammer. That is, the implementation signature does not form part of the method's public contract; it only enforces the internal contract.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. I see why now... This works. Sorry for any confusion.

@benlesh benlesh merged commit 9ee234d into ReactiveX:master Oct 5, 2017
@cartant cartant deleted the issue-2889 branch March 31, 2018 02:25
@lock
Copy link

lock bot commented Jun 5, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 5, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants