-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Rewrite the documentation about why the typescript types can not be inferred #2900
base: main
Are you sure you want to change the base?
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll leave @devanshj for detailed reviews.
foo: 0, | ||
bar: () => get(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is required to reproduce the problem. Otherwise, it would have been easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bring back bar: () => get()
and add some text about how the ts behavior related to real-world scenario
The problem with this PR is that it makes it look as if TypeScript is doing it's best and is correct whereas it can do better. I've opened an issue in TypeScript to know which feature will enable the inference we want. Once we know that we can just link to that issue. I don't think we need this explanation of how TypeScript's current inference algorithm works as it's not that complicated now. Or maybe we can keep it. I'll let @dai-shi decide that. |
After reading the microsoft/TypeScript#49618 and microsoft/TypeScript#60922 as your issue referred, I admit that there are some point I am missing, it does relate to the "chicken and egg" problem Let me prove this: function test<T>(fn: (prev: T) => T) { }
test((prev) => ({ a: 1 })); // T is inferred as "unknown" My initial point: And the point can be easily broken if we try function test<T>(fn: (prev: NoInfer<T>) => T) { }
test((prev) => ({ a: 1 })); // T is inferred as "unknown" We already tell the engine that never cares about As the typescript team pointed out function test<T>(fn: (prev: NoInfer<T>) => T) { }
test((prev) => {
return prev ? 1:0
}); if the output type relates to input type, typescript will refuse to do anything
maybe we should consider avoiding such usage altogether declare const create: <T>() => T
const x = create(() => ({
foo: 0,
bar: () => {
x.setState({foo:x.getState().foo+1})
},
}))
// OR
const y=create(()=>({
foo: 0,
}))
const bar=() => {
y.setState({foo:y.getState().foo+1})
} Or simply use https://zustand.docs.pmnd.rs/middlewares/combine |
As I wrote somewhere, Zustand's API design is JavaScript first, not TypeScript first. We are not changing the API anytime soon. The current typing is hacky, but it's been doing well. Moving forward, I think what we should do is to recommend |
As discussed in #2895