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 Typescript 5.6.x support by introducing esnext iterator helpers (#3927) #3935

Conversation

tonyraoul
Copy link
Contributor

@tonyraoul tonyraoul commented Oct 8, 2024

Code change checklist

  • Added/updated unit tests
  • Updated /docs. For new functionality, at least API.md should be updated
  • Verified that there is no significant performance drop (yarn mobx test:performance)

Context

Fixes #3927

Purpose of the PR

TypeScript 5.6.x introduces new Iterator Helper Methods that enhance the IterableObject interface with methods like map, flatMap, take, and drop. However, when the esnext target is enabled, MobX becomes incompatible as its current implementation lacks these methods, resulting in type errors.

This PR addresses the compatibility issues by:

  • Updating the IterableObject Interface: Aligning MobX’s implementation with TypeScript’s updated type definitions to prevent type errors.
  • Integrating Support for Iterator Helper Methods: Adding the new methods within MobX and enabling conditional polyfill support for environments that do not natively implement them.

Copy link

changeset-bot bot commented Oct 8, 2024

🦋 Changeset detected

Latest commit: 3e17e81

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
mobx Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

export function makeIterable<T, TReturn = unknown>(
iterator: Iterator<T>
): IteratorObject<T, TReturn> {
return Object.assign(Object.create(Iterator.prototype), iterator)
Copy link
Contributor Author

@tonyraoul tonyraoul Oct 8, 2024

Choose a reason for hiding this comment

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

Intentionally avoiding the usage of Iterator.from due to limited availability, using this instead to conditionally add helper functions IIF they are available within runtime either natively or via polyfill.

@tonyraoul tonyraoul marked this pull request as ready for review October 8, 2024 17:27
@tonyraoul tonyraoul changed the title [WIP] Fix Typescript 5.6.x support by introducing esnext iterator helpers (#3927) Fix Typescript 5.6.x support by introducing esnext iterator helpers (#3927) Oct 8, 2024
Copy link
Member

@mweststrate mweststrate left a comment

Choose a reason for hiding this comment

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

This looks great, thanks a lot!

@mweststrate mweststrate merged commit f91d2e1 into mobxjs:main Oct 15, 2024
1 check passed
@github-actions github-actions bot mentioned this pull request Oct 15, 2024
@zeldigas
Copy link

@mweststrate it seems that it is still not fixed. While typecheck is good, I got the following error with typescript 5.6.3 and mobx 6.13.4:

@app/app:test:  FAIL  src/components/organisms/component.store.test.ts > ComponentStore > some test
@app/app:test: ERROR: command finished with error: command (/workspace/master/packages/app) /usr/local/bin/pnpm run test exited (1)
@app/app:test: ReferenceError: Iterator is not defined
@app/app:test:  ❯ makeIterable ../../node_modules/.pnpm/[email protected]/node_modules/mobx/src/utils/iterable.ts:4:40
@app/app:test:  ❯ makeIterableForSet ../../node_modules/.pnpm/[email protected]/node_modules/mobx/src/types/observableset.ts:349:12
@app/app:test:  ❯ ObservableSet.values ../../node_modules/.pnpm/[email protected]/node_modules/mobx/src/types/observableset.ts:237:16
@app/app:test:  ❯ ObservableSet._proto.<computed> ../../node_modules/.pnpm/[email protected]/node_modules/mobx/src/types/observableset.ts:334:21
@app/app:test:  ❯ _createForOfIteratorHelperLoose ../../node_modules/.pnpm/[email protected]/node_modules/mobx/dist/mobx.cjs.development.js:308:24
@app/app:test:  ❯ ObservableSet.forEach ../../node_modules/.pnpm/[email protected]/node_modules/mobx/src/types/observableset.ts:110:9
@app/app:test:  ❯ ComponentStore.call src/components/organisms/component.store.ts:117:31

@app/app:test:     115|   get property(): Abc[] {
@app/app:test:     116|     const array: Abc[] = [];
@app/app:test:     117|     this.uiData.xyz.forEach((selected, item) => {
@app/app:test:        |                               ^
@app/app:test:     118|       if (selected) {
@app/app:test:     119|         array.push(item);

xyz property in code is initialized as xyz: new Set<Abc>() and is located in class that is made autoobservable

@tonyraoul
Copy link
Contributor Author

tonyraoul commented Oct 16, 2024

@app/app:test: ReferenceError: Iterator is not defined @zeldigas
what's your estarget ?

Most likely it's this line
https://github.com/mobxjs/mobx/pull/3935/files#diff-22d6d812427f3e234cc1b5448baf52696bc9a71646c71128e752c61c8a789c31R4

I believe Iterator isn't available to your environment.
FWIW Iterator is not available before es2015, or might be that your setup is missing a lib.

I am a bit unsure about compatibility requirements for mobx, but let me know more about your case maybe I missed something.

@zeldigas
Copy link

The project I'm working on have specific setup, with mixed use of es5 and es2022 in package.json files. Quick update all the places to es2022 did not help. I'll check in more details later today. Overal of course it's good to provide some isolated example of failure, this is clear..

@tonyraoul
Copy link
Contributor Author

tonyraoul commented Oct 16, 2024

apologies @zeldigas I believe it's not working on safari apparently, thanks for reporting! working on a proper fix.
my apologies for any inconveniences.

@tonyraoul
Copy link
Contributor Author

I believe I misunderstood MDN reference reporting that Iterator.prototype is widely available but that's not the case 🤔

@tonyraoul
Copy link
Contributor Author

tonyraoul commented Oct 16, 2024

my apologies, here is the fix #3943

@jansav
Copy link

jansav commented Nov 11, 2024

FYI: This PR introduced breaking change by utilizing MapIterator which was introduced in typescript 5.6. It was very annoying to debug why all types break when mobx-version was updated based on semver rules from 6.12.4 -> 6.13.5.

This means that 6.13.x version requires at least typescript 5.6.

@thisisanto
Copy link

thisisanto commented Nov 15, 2024

FYI: This PR introduced breaking change by utilizing MapIterator which was introduced in typescript 5.6. It's was very annoying to debug why all types break when mobx-version was updated based on semver rules from 6.12.4 -> 6.13.5.

This means that 6.13.x version requires at least typescript 5.6.

Plus 1 this is a breaking change that's disguised as a patch. Should probably be reverted, and re-introduced along with the appropriate peerDependency bump to [email protected] @tonyraoul

@tonyraoul
Copy link
Contributor Author

apologies for the inconvenience @jansav @thisisanto
I will start working on a fix, if you don't mind I will be adding another patch rather than unpublish this one since I am not a maintainer, hopefully it gets picked up soon.

Thanks for your valuable feedback.

@tonyraoul
Copy link
Contributor Author

tonyraoul commented Nov 15, 2024

Working on a fix here let me know if you have any thoughts please.
For context this happened many times before #3903

It might be a good idea to enable skipLibCheck within your project tsconfig.json

update: I've closed the "Fix" PR for now as it doesn't bring any value vs enabling skipLibCheck, please let me know if you think otherwise.

@mweststrate
Copy link
Member

@thisisanto @jansav to confirm: we (try to) always release against the latest version of TypeScript (which itself doesn't follow any versioning scheme), and strongly recommend to use skipLibCheck true. For some more details behind the rationale, see #3903 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Typescript 5.6.x compatibility with ObservableSet and Observable Map
5 participants