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

Support subclassing Observable with non-class constructor functions. #7640

Merged
merged 2 commits into from
Feb 2, 2021

Conversation

benjamn
Copy link
Member

@benjamn benjamn commented Feb 2, 2021

Now that the zen-observable-ts package has the ability to export Observable as a native ECMAScript class (#7615), we need to be careful when extending Observable using classes (like ObservableQuery and Concast) that have been compiled to ES5 constructor functions (rather than native classes), because the generated _super.call(this, subscriber) code throws when _super is a native class constructor (#7635).

Rather than attempting to change the way the TypeScript compiler transforms super(subscriber) calls, this commit wraps Observable.call and Observable.apply to work as expected, using Reflect.construct to invoke the superclass constructor correctly, when the Reflect API is available.

Another option would be to ship native class and super syntax with @apollo/client, by changing the "target" in tsconfig.json from "es5" to "es2015" or later, so consumers of @apollo/client code would be forced to compile native
class syntax however they see fit. That would be a more disruptive change, in part because it would prevent subclassing Apollo Client-exported classes using anything other than native class syntax and/or the Reflect.construct API, which is the very same problem this commit is trying to fix for the Observable class.

Now that the zen-observable-ts package has the ability to export
Observable as a native class (#7615), we need to be careful when extending
Observable using classes (like ObservableQuery and Concast) that have been
compiled to ES5 constructor functions (rather than native classes),
because the generated _super.call(this, subscriber) code throws when
_super is a native class constructor (#7635).

Rather than attempting to change the way the TypeScript compiler
transforms super(subscriber) calls, this commit wraps Observable.call and
Observable.apply to work as expected, by using Reflect.construct to invoke
the superclass constructor correctly, when the Reflect API is available:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/construct

Another option would be to ship native class syntax with @apollo/client,
by changing the "target" in tsconfig.json from "es5" to "es2015" or later,
so that consumers of @apollo/client would be forced to compile native
class syntax however they see fit. That would be a more disruptive change,
in part because it would prevent subclassing Apollo Client-defined classes
using anything other than native class syntax and/or the Reflect.construct
API, which is the very same problem this commit is trying to fix for the
Observable class.
@benjamn benjamn added this to the Release 3.4 milestone Feb 2, 2021
@benjamn benjamn self-assigned this Feb 2, 2021
@benjamn
Copy link
Member Author

benjamn commented Feb 2, 2021

Another option: I could move this logic into zen-observable-ts/module.js, so it would only be applied when the native Observable class is imported.

@benjamn benjamn merged commit 5e9821f into release-3.4 Feb 2, 2021
@benjamn benjamn deleted the 7635-fix-subclassing-Observable branch February 2, 2021 21:31
@hwillson hwillson removed this from the MM-2021-06 milestone Jul 29, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 15, 2023
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.

3 participants