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

Observable does not implement InteropObservable #3890

Closed
felixfbecker opened this issue Jul 4, 2018 · 10 comments
Closed

Observable does not implement InteropObservable #3890

felixfbecker opened this issue Jul 4, 2018 · 10 comments
Labels
TS Issues and PRs related purely to TypeScript issues

Comments

@felixfbecker
Copy link
Contributor

felixfbecker commented Jul 4, 2018

Bug Report

Current Behavior
I am trying to write a library interface that accepts InteropObservable for two reasons:

  • to allow any Observable implementation to be passed
  • I don't want to use Observable as an input type, because it is a class, and TypeScript will therefor reject passing in an instance of RxJS Observable if it is an instance of Observable from a different file (different package version, or duplicate because of npm link). Coding against interfaces is better than coding against implementations

I get the error:

Type 'Observable<T>' is not assignable to type 'InteropObservable<T>'.
      Property '[Symbol.observable]' is missing in type 'Observable<T>'.

Reproduction

Expected behavior

I would expect to be able to have my interface accept InteropObservable, and pass in an RxJS concrete Observable without a compile error.

Environment

  • Runtime: any
  • RxJS version: 6.2.1

Possible Solution
Add symbol.observable to Observable, and make it implement InteropObservable?

@kwonoj
Copy link
Member

kwonoj commented Jul 4, 2018

Interesting. afaik InteropObservable is supposed to let rx's Observable accepts other observables, not in opposite way (that InteropObservable doesn't represent Observable).

Still, I thought Observable already implemented Symbole.observable at least? 🤔 Don't recall exact history around those.

@cartant
Copy link
Collaborator

cartant commented Jul 4, 2018

Adding [Symbol.observable] to Observable sounds pretty reasonable, to me.

@kwonoj
Copy link
Member

kwonoj commented Jul 4, 2018

Me too, just thought we already did it. Not sure if it's related with decision we removed polyfill to symbol.observable?

@cartant
Copy link
Collaborator

cartant commented Jul 4, 2018

Observable does appear to be implement [Symbol.observable].

@felixfbecker
Copy link
Contributor Author

It definitely is not in the published .d.ts: https://unpkg.com/[email protected]/internal/Observable.d.ts

@cartant
Copy link
Collaborator

cartant commented Jul 4, 2018

This looks to be a TypeScript issue, as this:

import { EMPTY, InteropObservable } from "rxjs";
import { observable } from "rxjs/internal/symbol/observable";

class Something {
  [observable]() { return EMPTY; }
}
declare const s: Something;
const i: InteropObservable<never> = s;

effects this error:

[ts]
Type 'Something' is not assignable to type 'InteropObservable<never>'.
  Property '[Symbol.observable]' is missing in type 'Something'.

@cartant
Copy link
Collaborator

cartant commented Jul 4, 2018

@felixfbecker Its being missing could be related to what appears to be a TypeScript problem.

@cartant
Copy link
Collaborator

cartant commented Jul 4, 2018

Actually, it's not TypeScript. The problem - well, at least part of the problem - is that the InteropObservable declaration does not use the const that's in src/internal/symbol/observable.ts. It uses Symbol.observable directly:

export type InteropObservable<T> = { [Symbol.observable]: () => Subscribable<T>; };

Basically, it does so because TypeScript will not allow the observable constant/ponyfill to be used in the InteropObservable declaration:

[ts] A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.

Changing the snippet to this works fine:

import { EMPTY, InteropObservable } from "rxjs";

class Something {
  [Symbol.observable]() { return EMPTY; }
}
declare const s: Something;
const i: InteropObservable<never> = s;

@kwonoj kwonoj added the TS Issues and PRs related purely to TypeScript issues label Jul 10, 2018
@BioPhoton
Copy link
Contributor

@cartant as we have a solution posted in your last comment I believe we can close this issue

@benlesh
Copy link
Member

benlesh commented Jul 8, 2020

I believe that there's not much more we can do for this issue at this time. There's an adequate workaround in this comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
TS Issues and PRs related purely to TypeScript issues
Projects
None yet
Development

No branches or pull requests

5 participants