You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Thanks for your amazing work on this library! I'm a big fan of the approach you have taken with Zod of defining a type's schema only once rather than duplicatively for each type and its parser.
The one major downside I have found with using Zod for declaring types is that Visual Studio Code (and I assume the TypeScript language server more generally) does not seem to be able to connect usages of object properties back to their declaration in z.object.
Using any language server action like Go To Definition, Find Usages or Rename Symbol on Example["property"] does not work. This is a particular pain point for Rename Symbol, which is incredibly useful when working on a large code base.
I assume this is a limitation of the Typescript language server given the specific type-level programming that Zod is using. However, these features do appear to work with io-ts (a library that takes a similar approach), which makes me think it may be possible to implement Zod's type mappings in a way that preserves these IDE features, at least for some scenarios.
Is this a valuable goal to pursue, or have I misunderstood how most people are using Zod?
Digging a little deeper, TypeScript does not appear to be able to connect the properties in an object to those same properties in its associated mapped type if the keys are changed. This appears to be what is causing the IDE features to not work. For example, consider a simplified version of the return type of objectType in Zod:
This code is responsible for making schemas marked with .optional() optional (rather than just undefined) in the final object type. The addQuestionMarks type is transforming the keys in T using optionalKeys and requiredKeys. Due to these transformations of the keys of T, TypeScript can no longer connect the original type's keys to the mapped type's keys. As a result, using Go To Definition on property on the line starting with const instance2 does not work.
However, I believe we can get the same outcome in a way that preserves the IDE features:
All I have done is changed [k in optionalKeys<T>]?: T[k]; to [k in keyof T]?: T[k];. Using Go To Definition and Rename Symbol on property on the line starting with const instance3 now works as you would expect.
I believe this works because { [k in keyof T]?: T[k]; } directly passes on the keys of T without transforming them. This allows TypeScript to connect the original type with the mapped type. We then rely on the fact that { a?: A | undefined } & { a: A } merges to { a: A }, giving us the original type mapping behaviour.
What do you think? Is it worth seeing whether these sorts of changes can improve the IDE experience when using Zod?
The text was updated successfully, but these errors were encountered:
I don't have any first hand knowledge of what might be going on here, but I think if we can make a backwards compatible change that preserves our existing behavior and doesn't add much maintenance or cognitive overhead, I'm absolutely thrilled to help get a PR merged that improves editor ergonomics.
I think the one thing I would want to see in a PR that updates this type is some additional type-level tests to ensure we're not breaking anything in the ecosystem, so feel free to open a PR with these changes and we can get that going together.
Thanks for your amazing work on this library! I'm a big fan of the approach you have taken with Zod of defining a type's schema only once rather than duplicatively for each type and its parser.
The one major downside I have found with using Zod for declaring types is that Visual Studio Code (and I assume the TypeScript language server more generally) does not seem to be able to connect usages of object properties back to their declaration in
z.object
.For example, consider the following code:
Using any language server action like Go To Definition, Find Usages or Rename Symbol on
Example["property"]
does not work. This is a particular pain point for Rename Symbol, which is incredibly useful when working on a large code base.I assume this is a limitation of the Typescript language server given the specific type-level programming that Zod is using. However, these features do appear to work with io-ts (a library that takes a similar approach), which makes me think it may be possible to implement Zod's type mappings in a way that preserves these IDE features, at least for some scenarios.
Is this a valuable goal to pursue, or have I misunderstood how most people are using Zod?
Digging a little deeper, TypeScript does not appear to be able to connect the properties in an object to those same properties in its associated mapped type if the keys are changed. This appears to be what is causing the IDE features to not work. For example, consider a simplified version of the return type of
objectType
in Zod:This code is responsible for making schemas marked with
.optional()
optional (rather than justundefined
) in the final object type. TheaddQuestionMarks
type is transforming the keys inT
usingoptionalKeys
andrequiredKeys
. Due to these transformations of the keys ofT
, TypeScript can no longer connect the original type's keys to the mapped type's keys. As a result, using Go To Definition onproperty
on the line starting withconst instance2
does not work.However, I believe we can get the same outcome in a way that preserves the IDE features:
All I have done is changed
[k in optionalKeys<T>]?: T[k];
to[k in keyof T]?: T[k];
. Using Go To Definition and Rename Symbol onproperty
on the line starting withconst instance3
now works as you would expect.I believe this works because
{ [k in keyof T]?: T[k]; }
directly passes on the keys ofT
without transforming them. This allows TypeScript to connect the original type with the mapped type. We then rely on the fact that{ a?: A | undefined } & { a: A }
merges to{ a: A }
, giving us the original type mapping behaviour.What do you think? Is it worth seeing whether these sorts of changes can improve the IDE experience when using Zod?
The text was updated successfully, but these errors were encountered: