Skip to content

fix(goctl): recurse into inline struct in IsTagMember#5671

Open
014-code wants to merge 1 commit into
zeromicro:masterfrom
014-code:fix/istagmember-inline-recurse
Open

fix(goctl): recurse into inline struct in IsTagMember#5671
014-code wants to merge 1 commit into
zeromicro:masterfrom
014-code:fix/istagmember-inline-recurse

Conversation

@014-code

@014-code 014-code commented Jul 3, 2026

Copy link
Copy Markdown

概述

Fix #4800: goctl api ts
generates a spurious headers parameter on TypeScript request functions
when the request type contains an inline (anonymous-embedded) struct.

Root cause: Member.IsTagMember unconditionally returned true for any
tag key on an inline member, instead of recursing into the members of
the referenced struct. That made tsgen.hasRequestHeader (which calls
GetTagMembers("header")) treat every inline struct as having
header-tagged fields and emit a headers parameter even when the
interface defines no header field at all.

变更内容

  • tools/goctl/api/spec/fn.go
    • IsTagMember now first checks the member's own tags.
    • For inline members, it recurses into the DefineStruct or
      NestedStruct referenced by Type.Members and only returns true
      when a child actually carries the requested tag.
  • tools/goctl/api/spec/fn_test.go (new)

测试

  • Unit: go test ./tools/goctl/api/spec/ -v
    • 10 new subtests + 1 regression test, all PASS alongside the
      pre-existing 4 tests in the package.
  • End-to-end: reproduced the minimal .api from When generating TypeScript code, there is an additional headers parameter #4800 (an inline
    Pagination struct with only json tags) with
    go run ./tools/goctl/goctl.go api ts -api demo.api -dir out.
    The generated queryUserList function now takes only req — the
    spurious headers parameter is gone.

是否有破坏性变更?

否. The new behavior of IsTagMember is consistent with its existing
docstring ("returns true if the member contains the given tag"); an
inline member that carries no matching tag should not have reported
true before this fix either. No real consumer relies on the old
always-true behavior — it was the source of the bug itself.

Fixes #4800

Inline (anonymous-embedded) struct members carry no tag of their own;
their tag semantics live on the child members of the referenced struct.
IsTagMember previously returned true for any tag key on an inline
member, which made tsgen treat every inline struct as having
header-tagged fields and emit a spurious headers parameter on the
generated TypeScript request function.

Recurse into the referenced struct's children for inline members,
returning true only when an actual child carries the requested tag.

Fixes zeromicro#4800
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When generating TypeScript code, there is an additional headers parameter

1 participant