Skip to content

PoC: visibility-based model splitting in typespec-ts emitter - #5081

Draft
JialinHuang803 wants to merge 3 commits into
Azure:mainfrom
JialinHuang803:poc/visibility-model-split
Draft

PoC: visibility-based model splitting in typespec-ts emitter#5081
JialinHuang803 wants to merge 3 commits into
Azure:mainfrom
JialinHuang803:poc/visibility-model-split

Conversation

@JialinHuang803

@JialinHuang803 JialinHuang803 commented Jul 28, 2026

Copy link
Copy Markdown
Member

PoC: visibility-based model splitting in typespec-ts

Experimental, flag-gated emitter feature that prevents read-only properties (e.g. required @visibility(Lifecycle.Read) ARM props like id/name) from leaking into generated input types. When enabled, a request-body model is projected to its write view (WidgetCreate, WidgetCreateOrUpdate, ...) while responses keep the full read model.

Tracks #4710.

Design

  • Pure JS-emitter implementation in src/modular/helpers/visibility-helpers.ts — no TCGC changes beyond the public SdkModelType shape and the stable @typespec/http visibility helpers (resolveRequestVisibility, createMetadataInfo, getVisibilitySuffix).
  • Runs as a pre-pass (applyVisibilityModelSplit) right before visitPackageTypes, so the repointed graph is what gets emitted.
  • Gated by experimental-split-models-by-visibility (default OFF).
  • See packages/typespec-ts/design/visibility-model-split-design.md.

Included scenarios (visibility-scenarios/)

Runnable projects (spec + tspconfig.yaml + generated code) to eyeball output:

  • 01-widget-create — split (WidgetCreate) plus a no-read-only model that collapses to itself (Gadget, shared request/response, no rename).
  • 02-nested-createorupdate — recursive split (ACreateOrUpdate + BCreateOrUpdate) and nested-change propagation (CCreate synthesized purely because nested D must change).
  • 03-name-collision — a user-declared WidgetCreate collides with a synthesized one; binder falls back to positional WidgetCreate_1 (open question).

Notes

  • Draft / PoC — unit tests are intentionally excluded from this PR.
  • Scenarios 04-07 (gap cases: discriminated unions, spread bodies, used-as-both, cyclic models) are pending review and not included yet.

JialinHuang803 and others added 2 commits July 28, 2026 16:51
Adds an experimental, flag-gated (experimental-split-models-by-visibility,
default OFF) emitter pre-pass that projects request-body models to their write
visibility so read-only properties (e.g. required @visibility(Lifecycle.Read)
ARM props) no longer leak into generated input types.

Implemented entirely in the JS emitter (src/modular/helpers/visibility-helpers.ts),
with no TCGC changes beyond the public SdkModelType shape and the stable
@typespec/http visibility helpers. Includes runnable scenarios 01-03
(split, collapse, nested propagation, name collision) with generated output.

Tests are intentionally excluded from this draft PoC.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 742ec718-6a39-4e6d-bf72-74d80f6a2b9e
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 742ec718-6a39-4e6d-bf72-74d80f6a2b9e
@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:typescript Issues for @azure-tools/typespec-ts emitter label Jul 28, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jul 28, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@azure-tools/typespec-ts@5081

commit: 7db365f

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

❌ There is undocummented changes. Run chronus add to add a changeset or click here.

The following packages have changes but are not documented.

  • @azure-tools/typespec-ts
Show changes

@azure-sdk-automation

Copy link
Copy Markdown
Contributor

You can try these changes here

🛝 Playground 🌐 Website

Route any model in a discriminated hierarchy (base or a subtype reached
directly) through the discriminator root so the whole subtype tree is
projected together and cached once. This fixes the unresolved polymorphic
placeholder in write bodies and prevents a subtype used directly (e.g. a
Cat body) from producing a duplicate CatCreate.

Add scenario 04-discriminated-polymorphic (with a subtype-first createCat
operation) and document it in the design doc Scenarios section.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 742ec718-6a39-4e6d-bf72-74d80f6a2b9e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:typescript Issues for @azure-tools/typespec-ts emitter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant