spell a self-referencing untagged map member as an index signature, where the mapped type cycled - #233
Merged
Merged
Conversation
…here the mapped type cycled
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.
A self-recursive untagged enum whose recursive member is a map generates a TypeScript type alias that references itself through
Partial<Record<string, Self>>. TypeScript resolves mapped types while it resolves the alias declaring them, so the alias is refused outright:error TS2456: Type alias circularly references itself. The array member never had this problem — only the map spelling did.The fix is spelling-only: when the map's value type references the enclosing self type (the same test the zod renderer already applies for its
z.lazydeferral), the member is written as the index-signature object it is equal to —{ [key: string]: V | undefined }— which TypeScript resolves lazily. Every other map keeps the byte-identicalPartial<Record<..>>: non-recursive maps, array-wrapped maps (the wrap already defers), and maps whose key does not spell asstringornumber(an index signature has no parameter type for those; that keyed-by-enum case is tracked separately). Zod and JSON Schema surfaces are untouched.Tests pin the new spelling on the recursive fixture, the preserved spelling on a new non-recursive one, and the negative assertions on both; verified externally with
tsc --strict: the new alias compiles clean, the old spelling reproduces TS2456. Full feature-combination matrix green.