-
-
Notifications
You must be signed in to change notification settings - Fork 359
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
Incorrect field.state.value type #705
Comments
This is typed properly and this is not a bug. What you're doing by type-casting Instead, I'd propose passing |
I'm not sure I fully understand, could you explain a bit more? Is the argument here that there is no way to tell Also did not fully follow what you meant by breaking my own guidance? And the suggestion of passing |
Sure! Lemme start with an analogy, since I think it's important to communicate the headspace you need to get into for TanStack projects to really click (IMO, anyway): Say I'm at a party and a person and I are meeting for the first time. I assume, based on what their friends are calling them at this party, that their name is "Benny". But suppose that this is a semi-formal event and they prefer to be called their full name "Benjamin" in those contexts. This is the difference between type inferencing and explicit type passing: Inferencing might be accurate in some/most instances based on context clues, but when provided with explicit instructions, we must throw away the existing inferenced data This isn't just a courtesy in the programming world, either, TypeScript literally does not provide us the inferred data once you pass explicit an type to a generic. function identity<T>(v: T) {
return v;
}
// Inferred as `1`, not explicit
identity(1);
// Explicitly `number`, `1` inferred type is lost
identity<number>(1); Moreover, even if we could, consider what would happen if I decided to shorten Benjamin's name to "Ben" without asking. That might come across as rude or jarring, as I was explicitly told by Benjamin what they wanted to be called. This, too, is similar to our type system for Form. If you explicitly tell us "s is a string" and we type cast it to be "s is a string OR undefined" without asking your permission (ala, some kind of "partial" flag or something) then that behavior will cause headaches and problems in a different way than you're running into. Hopefully this helps explain a bit of why it works the way it does in TanStack Form? :) |
Sure I get that providing an explicit type will tell TS to use that type, but I think that only fairly applies in the example because the explicit type is wider than the passed in literal. For example TS would not allow us to say
And I think this is essentially one of the two possible solutions that could be considered here. If the user tells the library that this will be the data type, but it does not provide the correct data to satisfy that type then they should be warned about this. Personally this would be my preference, but perhaps there is a use case for a user providing a type and still not passing in that type. I see that your library will correctly prevent me from passing a default of
And indeed TS would now type this return type as
would provide a correct solution, but I'm not sure all of this is needed if there isn't a use case for the above scenario. Again usually when we tell a thing that its type will be T as a generic this is not the same thing as using the keyword |
Ahh okay, most of the time I get requests akin to this, it's often because someone is asking for incorrect type narrowing The problem with the () problem here is that we can't easily infer the empty usage of () and pass it all the way through to field.state.value. Just the complexity of our types. I'm gonna keep this closed as this feels pseudo intentional to me, but if you're able to make a PR that fixes empty functions specifically we'll likely merge it |
Describe the bug
I'm wondering if this was a design decision (I've seen it in RHF), but I feel like it is still incorrectly typed somewhere. A Field's field.state.value will have whatever type the useForm hook is given for that field. This is often correct, but when a default value is not provided the field can actually be
undefined
. This can be the cause behind components switching between controlled/uncontrolled or just general issues from having invalid types.Your minimal, reproducible example
https://codesandbox.io/p/sandbox/tanstack-form-d2rpvg?file=%2Fsrc%2FApp.tsx%3A20%2C7
Steps to reproduce
Hover over field.state.value
Expected behavior
As a user, I expected TS values to be correct, but I'm seeing that this field has a value that is not correctly captured by the provided TS constraints.
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
TanStack Form adapter
react-form
TanStack Form version
v0.19.5
TypeScript version
v5
Additional context
No response
The text was updated successfully, but these errors were encountered: