Fix TypeScript generator to correctly handle inline/embedded structs #5219
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.