Repository navigation
Add support for @discriminated unions - #6050
Joel Hendrix (jhendrixMSFT) wants to merge 1 commit into
Conversation
|
All changed packages have been documented.
Show changes
|
📦 Package size report1 package changed size, +3.21 KB (+0.0%) packed overall.
13 package(s) with no notable change
Packed = gzipped |
commit: |
Go emitter diffBaseline Diff summary: 39 file(s), +2967 / -3 Rendered diff: inline on the run summary, or the emitter-diff-go-html artifact. Informational check (core/eng/emitter-diff); does not block the PR. |
There was a problem hiding this comment.
🟡 Changes recommended
Union collection responses can fail generation or decoding due to missing union naming and discriminator-aware handling, while string-encoded numeric union examples produce uncompilable Go samples.
2 open issues
What changed in this PR
Adds Go emitter support for @discriminated unions using polymorphic interfaces and variant models. Unions without a base model reject unknown discriminator values rather than falling back to a base type.
Changes:
- Supports inline and object-envelope variants, custom property names, and example generation.
- Updates polymorphic code generation and fake-server handling.
- Adds scenario baselines, adaptation tests, and Spector coverage.
| File | Description |
|---|---|
| packages/typespec-go/test/unittest/type-adaptation.test.ts | Tests union interface and variant name collisions. |
| packages/typespec-go/test/unittest/scenarios/discriminated-unions.md | Adds generated baselines for unions, examples, and hierarchies. |
| packages/typespec-go/test/unittest/scenario-suites/discriminated-unions.test.ts | Registers the union scenario suite. |
| packages/typespec-go/test/unittest/scenario-runner.ts | Enables union inheritance in test fixtures. |
| packages/typespec-go/test/unittest/example-adaptation.test.ts | Tests nested example values and invalid discriminators. |
| packages/typespec-go/test/http-specs/type/union/disriminatedgroup/discriminatednoenvelopedefault_client_test.go | Tests default inline union requests and responses. |
| packages/typespec-go/test/http-specs/type/union/disriminatedgroup/discriminatednoenvelopecustomdiscriminator_client_test.go | Tests inline unions with a custom discriminator. |
| packages/typespec-go/test/http-specs/type/union/disriminatedgroup/discriminatedenvelopeobjectdefault_client_test.go | Tests default object-envelope unions. |
| packages/typespec-go/test/http-specs/type/union/disriminatedgroup/discriminatedenvelopeobjectcustomproperties_client_test.go | Tests custom envelope property names. |
| packages/typespec-go/test/http-specs/type/union/disriminatedgroup/discriminated_client_test.go | Tests invalid tags, null responses, serialization, and fake round trips. |
| packages/typespec-go/src/tcgcadapter/types.ts | Adapts unions into interfaces and concrete variants. |
| packages/typespec-go/src/tcgcadapter/clients.ts | Adapts union responses and raw example values. |
| packages/typespec-go/src/codemodel/type.ts | Makes polymorphic interface base models optional. |
| packages/typespec-go/src/codegen/fake/servers.ts | Preserves intermediate clients needed for nested server dispatch. |
| packages/typespec-go/src/codegen/core/polymorphics.ts | Emits decoding errors for unions without a fallback model. |
| packages/typespec-go/src/codegen/core/models.ts | Adds marker methods for union variants. |
| packages/typespec-go/src/codegen/core/interfaces.ts | Generates union interfaces without base-model accessors. |
| packages/typespec-go/src/codegen/core/helpers.ts | Handles interfaces without base models during serialization traversal. |
| packages/typespec-go/src/codegen/core/example.ts | Selects a concrete variant for generated placeholder examples. |
| packages/typespec-go/spector.config.http.yaml | Enables discriminated-union Spector scenarios. |
| .chronus/changes/main-2026-10-6-13-52-58.md | Documents the new Go emitter capability. |
Review effort: Balanced
|
You can try these changes here
|
f14cde6 to
4348232
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Helper discovery skips AnyResult response types, potentially leaving generated packages uncompilable, while discriminator decoding still fails for nested collections, fake request bodies, additional properties, and whitespace-padded null.
5 open issues
Discover collection helpers for AnyResult status types · New Accept whitespace-padded null in discriminator decoding · New Recursively decode discriminator interfaces inside collection types · New Decode collection request bodies in generated fake servers · New Decode discriminator values in additional properties · New
2 resolved since last review
Review effort: Balanced
| if (interfaceType.rootType) { | ||
| text += `${indent.get()}b = &${prefix}${interfaceType.rootType.name}{}\n`; | ||
| } else { | ||
| text += `${indent.get()}return nil, fmt.Errorf("unrecognized discriminator value %v for ${interfaceType.name}", m["${interfaceType.discriminatorField}"])\n`; |
| return unmarshallerText; | ||
| } | ||
| if (format === "JSON" || format === "XML") { | ||
| if (format === "JSON" && (go.isSlice(type, "interface") || go.isMap(type, "interface"))) { |
| if (type.discriminatedOptions && !this.getSseMetadata(type)) { | ||
| return this.getDiscriminatedUnion(type); |
| modelType.fields.push( | ||
| new go.ModelField("AdditionalProperties", addlPropsType, "", annotations), | ||
| ); | ||
| fields.push(new go.ModelField("AdditionalProperties", addlPropsType, "", annotations)); |
The generated code is polymorphic like for @Discriminator types, the only difference is there's no fallback base type.
4348232 to
a7e9906
Compare


The generated code is polymorphic like for Discriminator types, the only difference is there's no fallback base type.