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(vanilla): Improve Snapshot type so that it respects builtin objects #672

Merged
merged 15 commits into from
Feb 24, 2023

Conversation

octet-stream
Copy link
Contributor

Summary

This PR improves Snapshot type so that it does not affect builtin object, like Date.

Examples for old and new behaviours can be found in TS playground: for TS 3.5.1 and for TS 4.9.5. As you can see from the OldSnapshot example, it iterates through every member of Date, Map and Set object and converts these objects to readonly POJOs for some reason.

The solution might not be perfect though, so I would suggest adding some tests for typings (or maybe you already have and I just won't be able to find any, so please let me know).

Also, I wouldn't be able to run tests, because this project is hardly relying on Yarn, so will see if the tests are passing.

And lastly, I would like to ask if you can expose both Options (for useSnapshot hook) and Snapshot<T> types, so that people might implement extensions upon this hook and rely on public API.

Check List

  • yarn run prettier for formatting code and docs

@vercel
Copy link

vercel bot commented Feb 16, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated
valtio ✅ Ready (Inspect) Visit Preview 💬 Add your feedback Feb 18, 2023 at 1:09PM (UTC)

@codesandbox-ci
Copy link

codesandbox-ci bot commented Feb 16, 2023

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 092bec4:

Sandbox Source
React Configuration
React Typescript Configuration
React Browserify Configuration
React Snowpack Configuration
React Parcel Configuration

Copy link
Member

@dai-shi dai-shi left a comment

Choose a reason for hiding this comment

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

The change looks reasonable!

@dai-shi
Copy link
Member

dai-shi commented Feb 16, 2023

Thanks for your suggestions!

so I would suggest adding some tests for typings

Would you be able to help on it?

this project is hardly relying on Yarn

That's true, but I think you can run normal tests with npm test. (CI tests are really complicated.)

if you can expose both Options (for useSnapshot hook) and Snapshot types,

As you might guess, the first one can be extracted fairly easily, and the second one is intentional.

people might implement extensions upon this hook and rely on public API.

If they rely on internal types, I'd suggest to pin the valtio version and use it. We may really change them in the future without notice.

@dai-shi dai-shi changed the title Improve Snapshot type so that it respects builtin objects fix(vanilla): Improve Snapshot type so that it respects builtin objects Feb 16, 2023
@octet-stream
Copy link
Contributor Author

octet-stream commented Feb 16, 2023

Would you be able to help on it?

Yup, I think I can write bunch of tests for Snapshot type using something like tsd. But I am have no idea how to get this done for patches for TS 3.4

That's true, but I think you can run normal tests with npm test. (CI tests are really complicated.)

Nope, it doesn't work and I have to install Yarn. And maybe I will, it's just that I have to do this for such small thing. Not a big problem, I think. But having scripts running using npm might be more convenient, as it is the default (and I personally could've run tests via pnpm).

As you might guess, the first one can be extracted fairly easily, and the second one is intentional.

And so I did, yes, but it would be just much more handful to have useSnapshot Options to be part of the public API.

If they rely on internal types, I'd suggest to pin the valtio version and use it. We may really change them in the future without notice.

Alright then :)
Besides, for me, it's just a matter of typing the result of hook that wraps useSnapsoht to create a snapshot from useContext result.

@dai-shi
Copy link
Member

dai-shi commented Feb 16, 2023

Would you be able to help on it?

Yup, I think I can write bunch of tests for Snapshot type using something like tsd. But I am have no idea how to get this done for patches for TS 3.4

We can simply drop such tests for very old TS. Please make it a new test file.

That's true, but I think you can run normal tests with npm test. (CI tests are really complicated.)

Nope, it doesn't work and I have to install Yarn. And maybe I will, it's just that I have to do this for such small thing. Not a big problem, I think. But having scripts running using npm might be more convenient, as it is the default (and I personally could've run tests via pnpm).

Oops, my bad. My recent change requires yarn for test.
Yeah, we may consider improving those build/test scripts in the future and I hope to make it work with npm too.

@octet-stream
Copy link
Contributor Author

Added some tests for Snapshot type, ended up using ts-expect. They will be run through regular tsc --noEmit command.

src/vanilla.ts Outdated Show resolved Hide resolved
tests/typings/Snapshot.test-d.ts Outdated Show resolved Hide resolved
Copy link
Member

@dai-shi dai-shi left a comment

Choose a reason for hiding this comment

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

So, this needs to be changed to support custom classes?
Feels like we never reach an ideal solution. false positives are better than false negatives.

@octet-stream
Copy link
Contributor Author

Feels like we never reach an ideal solution. false positives are better than false negatives.

Can't agree with you more.
So I've added SnapshotIgonre union type with the list of objects that Snapshot will not turn into readonly. Please let me know if I've missed something.

@octet-stream octet-stream requested review from dai-shi and stephenh and removed request for dai-shi and stephenh February 17, 2023 09:08
@octet-stream
Copy link
Contributor Author

Out of curiosity: Why GitHub does not let me to request review from both of you at the same time? x)

Copy link
Member

@dai-shi dai-shi left a comment

Choose a reason for hiding this comment

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

I don't know if there are any edge cases uncovered. Seems reasonable. (And makes me feel Snapshot type will be INTERNAL forever.)

I'll wait for @stephenh 's review.

@octet-stream
Copy link
Contributor Author

Wellp, looks like I need yarn after all :)

@octet-stream
Copy link
Contributor Author

Fixed Snapshot type tests for TS 3.7. It appears that import type was introduced in 3.8.

@dai-shi
Copy link
Member

dai-shi commented Feb 18, 2023

It appears that import type was introduced in 3.8.

Nice catch!
In jotai, we have this patch:
https://github.com/pmndrs/jotai/blob/11add6285012fed1c9b25928e3d7ade694e3dd00/.github/workflows/test-old-typescript.yml#L53
but we didn't have it here..
(since jotai's minimal ts version is now 3.8, we can actually delete that line?? 🤔 )

Copy link
Member

@dai-shi dai-shi left a comment

Choose a reason for hiding this comment

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

LGTM.

Are you hesitant renaming the new file to tests/typings/snapshot.test.ts?

@octet-stream
Copy link
Contributor Author

Are you hesitant renaming the new file to tests/typings/snapshot.test.ts?

No, but this will require configuration for jest, I think. It should be ignored by it.

@octet-stream
Copy link
Contributor Author

octet-stream commented Feb 18, 2023

Didn't catch this one. For some reason VSCodium decided not to show ESLint errors for me :D

@dai-shi
Copy link
Member

dai-shi commented Feb 18, 2023

No, but this will require configuration for jest, I think. It should be ignored by it.

Oh, I wasn't aware that. Which part is bad? We have tests/snapshot.test.ts, so the typings subdir could be something, but not that one...

@octet-stream
Copy link
Contributor Author

octet-stream commented Feb 18, 2023

Which part is bad?

The part where jest will likely fail trying to run through this file :)
These test files should not be executed in runtime. They only meant for tsc typechecks.
But technically we could just ignore the whole typings directory for jest, I guess. Doesn't really matter where these tests placed, or how they named. They're just regular TypeScript files.

I can add configuration for jest and rename the file as you ask. If you insist :)

@dai-shi
Copy link
Member

dai-shi commented Feb 18, 2023

The part where jest will likely fail trying to run through this file :)

Ah, I thought the other way around.
Well, we run those type only tests with jest, so, it should be fine. Does it cause CI errors?

@octet-stream
Copy link
Contributor Author

Well, we run those type only tests with jest, so, it should be fine. Does it cause CI errors?

If jest will ignore test file without any test in it, then it should be fine. I'm not familiar with jest that much, but, for instance, AVA will fail in that case. So I just assumed it might have same behaviour, because it seem reasonable.

@octet-stream
Copy link
Contributor Author

Google says it will fail. So in that case we need to either ignore these files (as I suggested - the whole tests/typings directory), or add a noop test, or add todo test.

@dai-shi
Copy link
Member

dai-shi commented Feb 18, 2023

This is how it's done in jotai.
https://github.com/pmndrs/jotai/blob/main/tests/vanilla/types.test.tsx
So, it's a noop test?

@octet-stream
Copy link
Contributor Author

octet-stream commented Feb 18, 2023

It does seem like it. I don't see any use of jest's expect function. But they look like they're regular jest tests. I can rewrite these tests like this, if you want.

@octet-stream
Copy link
Contributor Author

Not sure though why do use have Component at the end of each test.

@dai-shi
Copy link
Member

dai-shi commented Feb 18, 2023

Not sure though why do use have Component at the end of each test.

I think some of eslint rules complain otherwise.

@dai-shi
Copy link
Member

dai-shi commented Feb 18, 2023

I can rewrite these tests like this, if you want.

Yeah, please try it for now. We'll revisit later with other repos. Or maybe with #646.

I may consider including typing tests in tests/snapshot.test.ts for now, as it works with ts 3.7.5. That makes all test files flat.

@octet-stream
Copy link
Contributor Author

I may consider including typing tests in tests/snapshot.test.ts for now, as it works with ts 3.7.5. That makes all test files flat.

I've merged typings tests file into tests/snapshot.test.ts.

Copy link
Member

@dai-shi dai-shi left a comment

Choose a reason for hiding this comment

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

Thanks for your contribution!!

tests/snapshot.test.ts Outdated Show resolved Hide resolved
@dai-shi dai-shi merged commit 09d7567 into pmndrs:main Feb 24, 2023
@octet-stream octet-stream deleted the fix/snapshot-type branch February 26, 2023 20:46
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.

3 participants