You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[TCGC] Convert inline discriminated unions to polymorphic models by default - #5743
Implement the non-envelope discriminated-union conversion agreed in #5703.
Convert eligible @discriminated(#{ envelope: "none" }) unions with an explicit named model base and nominally inherited model variants to the existing polymorphic SDK model representation by default.
Reuse the declared base model's name and identity, populate discriminator properties/tag values/subtype mappings, and preserve recursive references, containers, nullable uses, client names, enum discriminator types, usage, access, and serialization metadata.
Add convertDiscriminatedUnionsToModels: false to createSdkContext options so Rust and other emitters can retain native discriminated unions.
Leave ordinary unions, object envelopes, SSE event unions, structural-only alternatives, unconstrained unions, defaults, and base-model alternatives unconverted. Report an error for conflicting hierarchy metadata without overwriting existing metadata or changing the base-model alias.
Document eligibility, opt-out behavior, and the shared-base tradeoff: compatible unions share a combined subtype map rather than preserving per-union alternative subsets.
This PR is based on current main, does not depend on the separate union-variant-name work, and does not change language emitter code, the core submodule, or the lockfile.
Companion wire-contract scenarios: microsoft/typespec#12288. Per-language emitter integration and the SDK representation of envelope unions remain separate work.
Validation
Built TCGC and its workspace dependencies.
Complete TCGC suite: 1,705 passed, 2 skipped.
Repository-wide pnpm format and pnpm lint passed.
TCGC build and tests passed with Node.js 26.0.0.
Chronus change-description validation and git diff --check passed.
Convert inline-discriminated unions with explicit nominal model hierarchies to polymorphic SDK models by default. Set convertDiscriminatedUnionsToModels: false in createSdkContext to preserve union representations. Ordinary unions and object-envelope unions retain their existing behavior.
Packed = gzipped .tgz published to npm. Unpacked = total extracted size. 🆕 added, 🗑️ removed. Packages from the core/ submodule are not included. 🔴 grew · 🟢 shrank — only changes of at least 512 B and 0.5% are marked.
Preserve native union representations when the declared base is an alternative, including base-only unions, and update regression coverage and guidance.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fe48cf1c-c567-4896-b51d-5ae7233ae454
Keep the PR scoped to TCGC and retain the original base-alternative eligibility handling.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fe48cf1c-c567-4896-b51d-5ae7233ae454
With @discriminator("type") model PetBase { next?: Pet; type: string; }, Cat extends PetBase { type: "cat"; }, and an inline Pet extends PetBase { feline: Cat } using kind, visiting the base first reaches this guard before its discriminator is initialized (types.ts:1165). Conversion therefore misses the conflict; the later model-discriminator pass leaves both properties marked as discriminators and overwrites Cat's tag while retaining the union's subtype key. Validate the raw hierarchy metadata or defer conversion metadata changes until model initialization completes, preserving the union's base alias, and test both traversal orders.
Preserve exact-name flag for inherited discriminators
For an inherited discriminator named with @@clientName(PetBase.kind, exact("client_kind")), synthesis copies the source name but resets isExactName to false. TypeScript's normalizeSdkName (packages/typespec-ts/src/utils/name-utils.ts:223–235) then normalizes the subtype property to clientKind while the base retains client_kind. Copy the source's exact-name flag and add a regression assertion for the synthesized property.
…#12294)
Fix Java handling of tagged descendants behind untagged inheritance
intermediates.
- Do not manufacture an outer discriminator value from an intermediate's
class name or dispatch to it as a tagged subtype.
- Preserve TCGC's subtype map for usage propagation, so tagged
grandchildren are emitted without exposing unrelated descendants.
- Disable shared JSON helpers when an untagged node would cause
inherited fields to be skipped.
Regression coverage compiles generated models and checks deserialization
and JSON round trips with one/two intermediate levels and sharing
enabled/disabled. Genuine nested-discriminator metadata remains covered.
Validation: 136 generator-core tests and 53 emitter tests pass; emitter
build, type-check, lint, and formatting checks pass. Paired with the
TCGC build from Azure/typespec-azure#5743, both
transitive and ancestor/descendant UNION cases generate, compile, and
round-trip successfully. The direct MODEL/UNION control produces nine
byte-identical Java source files.
This does not fix the separate pre-existing TCGC omission in the
transitive MODEL setting.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 33054d5c-f968-4c4e-a9ac-19c8fe6994c4
This branch has not been deployed
No deployments
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
lib:tcgcIssues for @azure-tools/typespec-client-generator-core librarymeta:websiteTypeSpec.io updates
3 participants
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.
Summary
Implement the non-envelope discriminated-union conversion agreed in #5703.
@discriminated(#{ envelope: "none" })unions with an explicit named model base and nominally inherited model variants to the existing polymorphic SDK model representation by default.convertDiscriminatedUnionsToModels: falsetocreateSdkContextoptions so Rust and other emitters can retain native discriminated unions.This PR is based on current
main, does not depend on the separate union-variant-name work, and does not change language emitter code, thecoresubmodule, or the lockfile.Companion wire-contract scenarios: microsoft/typespec#12288. Per-language emitter integration and the SDK representation of envelope unions remain separate work.
Validation
pnpm formatandpnpm lintpassed.git diff --checkpassed.