Improve IDE integration for inferred object properties to support Go To Definition, Rename Symbol, etc.#1117
Merged
colinhacks merged 11 commits intocolinhacks:masterfrom May 6, 2022
Conversation
7c01ec3 to
bb257f6
Compare
bb257f6 to
fac389c
Compare
4271ae4 to
9b846c6
Compare
This was referenced May 9, 2022
MrAwesome
pushed a commit
to MrAwesome/zod
that referenced
this pull request
May 20, 2022
…To Definition, Rename Symbol, etc. (colinhacks#1117) * Increase test coverage for type inference of optional object properties * Add test showing that Go To Definition is broken on object properties * Fix Go To Definition for inferred object properties * Fix Go To Definition for inferred merged object properties * Improve languageServerFeatures test names * Fix Go To Definition for inferred pick object properties * Fix Go To Definition for inferred omit object properties * Exclude languageServerFeatures tests from deno * Fix keyof issue * 3.14.5 * Remove tc dep Co-authored-by: Colin McDonnell <colinmcd@alum.mit.edu>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR fixes the issue I raised here: #1115
To summarise, the properties of types declared using
z.inferonz.object({ ... })do not support IDE language server features such as Find All References, Rename Symbol or Go To Definition.To take a concrete example using the latest version of Zod in VS Code, the language server features
Find All References,Rename SymbolandGo To Definitiondo not work when you select the propertypropin the code below:As you no doubt know, these features are incredibly useful for working on TypeScript projects, particularly as they grow in size.
These features are broken because
z.object({ ... })uses a mapped type,addQuestionMarks, that transforms its keys usingrequiredKeysandoptionalKeys. Unfortunately, due to a limitation in the TypeScript compiler (microsoft/TypeScript#47813), transforming keys in a mapped type prevents the compiler from linking the mapped type properties to their definition.Fortunately, it is possible to preserve the behaviour of
addQuestionMarkswithout mapping the keys on one side of the intersection (by taking advantage of the fact that(T | undefined) & TequalsT):It appears that the built-in type helpers
OmitandPickare also special cased to preserve the linkage between mapped keys, so I was able to use those forobject({}).extend(),object({}).pick()andobject({}).omit():These changes preserve the existing behaviour while enabling the IDE features for
z.object({ ... })as well as when usingz.object({ ... }).merge(z.object({ ... })),z.object({ ... }).partial(),z.union(),z.object().pickandz.object().omit.I have added a number of tests that use the TypeScript language server (via the library
ts-morph) to verify that Go To Definition (and by extension the other features) work correctly. I have also added additional tests around the types inferred fromz.objectto ensure I have not broken existing behaviour.What do you think? Happy to make any changes. Thanks!