Fix TypeScript generator to correctly handle inline/embedded structs#5219
Draft
Fix TypeScript generator to correctly handle inline/embedded structs#5219
Conversation
Contributor
There was a problem hiding this comment.
Pull Request Overview
This PR fixes three critical issues with the TypeScript code generator for go-zero API definitions when handling inline/embedded structs. The fixes ensure proper TypeScript parameter generation and interface creation for embedded structs with different tag types.
Key Changes
- Added three new helper functions to recursively check for actual tag members in embedded structs
- Modified the TypeScript generation logic to use these helpers instead of surface-level member checks
- Added comprehensive test coverage for all new helper functions and end-to-end integration testing
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| tools/goctl/api/tsgen/util.go | Added three recursive helper functions for checking actual tag members in embedded structs |
| tools/goctl/api/tsgen/genpacket.go | Updated generation logic to use new helper functions for accurate parameter determination |
| tools/goctl/api/tsgen/util_test.go | Added comprehensive unit tests for all three new helper functions |
| tools/goctl/api/tsgen/gen_test.go | Added end-to-end integration test for inline struct handling scenarios |
Copilot
AI
changed the title
[WIP] Fix incorrect TypeScript code generated by goctl
Fix TypeScript generator to correctly handle inline/embedded structs
Oct 7, 2025
- Add hasActualTagMembers helper to recursively check for actual tag members - Add hasActualBodyMembers helper to recursively check for actual body members - Add hasActualNonBodyMembers helper to recursively check for actual non-body members - Update genParamsTypesIfNeed to use hasActualNonBodyMembers and hasActualTagMembers - Update hasRequestBody, hasRequestHeader, hasRequestPath, and pathHasParams to use new helpers - Add comprehensive test coverage for new helper functions Co-authored-by: kevwan <1918356+kevwan@users.noreply.github.com>
- Add TestGenWithInlineStructs to verify end-to-end generation - Test verifies correct parameter generation, flattening of inline structs - Test verifies no incorrect Headers interfaces are generated - Test verifies correct argument counts in function calls Co-authored-by: kevwan <1918356+kevwan@users.noreply.github.com>
Co-authored-by: kevwan <1918356+kevwan@users.noreply.github.com>
104fa70 to
02191e0
Compare
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.
Problem
The TypeScript code generator (
goctl api ts) was producing incorrect code when API definitions contained inline/embedded structs. This resulted in three distinct issues:Headersinterfaces that were never generatedParamsinterfacesExample
Given this API definition:
Before this fix, the generator produced:
After this fix:
Root Cause
The generator used
IsBodyMember()andIsTagMember()methods which returntruefor all inline/embedded members, regardless of whether they actually contain json/form/header/path tags. This caused:Headersinterfaces to be generated when embedded structs had no header tagsSolution
Implemented three recursive helper functions that properly distinguish between inline struct markers and actual tag presence:
hasActualTagMembers(tp, tagKey)- Recursively checks if a type actually has members with the specified tag (form/header/path)hasActualBodyMembers(tp)- Recursively checks if a type actually has body members (json tags)hasActualNonBodyMembers(tp)- Recursively checks if a type actually has non-body members (form/header/path tags)These functions traverse embedded structs recursively to find actual tagged members, rather than stopping at the inline marker.
Changes
Modified Files
tools/goctl/api/tsgen/util.gogenParamsTypesIfNeed()to usehasActualNonBodyMembers()andhasActualTagMembers()tools/goctl/api/tsgen/genpacket.gohasRequestBody()to usehasActualBodyMembers()hasRequestHeader()andhasRequestPath()to usehasActualTagMembers()pathHasParams()to usehasActualNonBodyMembers()Test Coverage
Verification
The generated TypeScript code now:
ParamsinterfacesHeadersinterfaces when actual header tags existFixes #4344
Original prompt
💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.