Skip to content

add back no unnamed types#4880

Open
iscai-msft wants to merge 9 commits into
Azure:mainfrom
iscai-msft:tcgc/addBackNoUnnamedTypes
Open

add back no unnamed types#4880
iscai-msft wants to merge 9 commits into
Azure:mainfrom
iscai-msft:tcgc/addBackNoUnnamedTypes

Conversation

@iscai-msft

@iscai-msft iscai-msft commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Replace the no-unnamed-union linter rule with no-unnamed-types in @azure-tools/typespec-azure-core. The new rule flags anonymous models in addition to unnamed unions, walking the type graph from operations to detect anonymous models on the client surface. The no-unnamed-types rule has been removed from @azure-tools/typespec-client-generator-core.

in type spec-next, 94 existing suppressions renamed, 28 net new suppressions added

Companion PR

@microsoft-github-policy-service microsoft-github-policy-service Bot added int:azure-specs Run integration tests against azure-rest-api-specs lib:tcgc Issues for @azure-tools/typespec-client-generator-core library meta:website TypeSpec.io updates linter Issues related to linter rules labels Jul 13, 2026
@azure-sdk-automation

azure-sdk-automation Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

All changed packages have been documented.

  • @azure-tools/typespec-azure-core
  • @azure-tools/typespec-azure-rulesets
  • @azure-tools/typespec-client-generator-core
Show changes

@azure-tools/typespec-azure-core - feature ✏️

Replace the no-unnamed-union linter rule with no-unnamed-types in @azure-tools/typespec-azure-core. The new rule flags anonymous models in addition to unnamed unions, walking the type graph from operations to detect anonymous models on the client surface. The no-unnamed-types rule has been removed from @azure-tools/typespec-client-generator-core.

@azure-tools/typespec-azure-rulesets - feature ✏️

Replace the no-unnamed-union linter rule with no-unnamed-types in @azure-tools/typespec-azure-core. The new rule flags anonymous models in addition to unnamed unions, walking the type graph from operations to detect anonymous models on the client surface. The no-unnamed-types rule has been removed from @azure-tools/typespec-client-generator-core.

@azure-tools/typespec-client-generator-core - feature ✏️

Replace the no-unnamed-union linter rule with no-unnamed-types in @azure-tools/typespec-azure-core. The new rule flags anonymous models in addition to unnamed unions, walking the type graph from operations to detect anonymous models on the client surface. The no-unnamed-types rule has been removed from @azure-tools/typespec-client-generator-core.

@azure-sdk-automation

Copy link
Copy Markdown
Contributor

You can try these changes here

🛝 Playground 🌐 Website

@pkg-pr-new

pkg-pr-new Bot commented Jul 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@azure-tools/typespec-azure-core@4880
npm i https://pkg.pr.new/@azure-tools/typespec-azure-rulesets@4880
npm i https://pkg.pr.new/@azure-tools/typespec-client-generator-core@4880

commit: 8a8a681

@github-actions

Copy link
Copy Markdown
Contributor

⚡ Benchmark Results

⚠️ 1 metric(s) regressed above the +5% threshold:

Metric Baseline Current Change
 ↳ linter/@azure-tools/typespec-client-generator-core/no-unnamed-types 🟢 0.0ms 🟢 2.9ms +100.0% 🔴
Full details – comparing 4656768 vs baseline rolling-baseline-f49cd9d-f3a0f6d (rolling baseline (20 main runs))
Metric Baseline Current Change
total 🔴 1.03s 🔴 938.0ms -8.5% 🟢
loader 🟡 310.9ms 🟡 275.5ms -11.4% 🟢
resolver 🟢 40.5ms 🟢 37.9ms -6.3% 🟢
checker 🟡 369.3ms 🟡 336.0ms -9.0% 🟢
validation 🟢 85.6ms 🟢 79.7ms -6.9% 🟢
 ↳ validation/@azure-tools/typespec-azure-core 🟡 12.8ms 🟡 11.7ms -8.4% 🟢
 ↳ validation/@typespec/http 🟡 15.7ms 🟡 14.7ms -6.4% 🟢
 ↳ validation/@typespec/rest 🟢 1.6ms 🟢 1.6ms -3.0%
 ↳ validation/@typespec/versioning 🔴 51.5ms 🔴 47.9ms -6.9% 🟢
 ↳ validation/compiler 🟢 3.9ms 🟢 3.6ms -6.7%
linter 🟡 218.5ms 🟡 208.2ms -4.7%
 ↳ linter/@azure-tools/typespec-azure-core/auth-required 🟢 0.1ms 🟢 0.1ms -5.2%
 ↳ linter/@azure-tools/typespec-azure-core/bad-record-type 🟢 0.6ms 🟢 0.6ms -4.1%
 ↳ linter/@azure-tools/typespec-azure-core/byos 🟢 8.5ms 🟢 8.2ms -2.9%
 ↳ linter/@azure-tools/typespec-azure-core/casing-style 🟢 1.5ms 🟢 1.4ms -6.8%
 ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance 🟢 0.2ms 🟢 0.2ms -6.3%
 ↳ linter/@azure-tools/typespec-azure-core/documentation-required 🟢 2.0ms 🟢 1.8ms -9.0%
 ↳ linter/@azure-tools/typespec-azure-core/friendly-name 🟢 1.4ms 🟢 1.4ms -2.9%
 ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required 🟢 0.4ms 🟢 0.3ms -11.5%
 ↳ linter/@azure-tools/typespec-azure-core/known-encoding 🟢 0.5ms 🟢 0.5ms -8.4%
 ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required 🟢 0.8ms 🟢 0.8ms -5.4%
 ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch 🟢 0.7ms 🟢 0.6ms -6.6%
 ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union 🟢 1.0ms 🟢 1.0ms -2.1%
 ↳ linter/@azure-tools/typespec-azure-core/no-enum 🟢 0.2ms 🟢 0.2ms -7.1%
 ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes 🟢 0.3ms 🟢 0.3ms -3.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops 🟢 0.2ms 🟢 0.2ms -0.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-format 🟢 0.8ms 🟢 0.9ms +3.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric 🟢 0.8ms 🟢 0.8ms -8.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🔴 27.2ms 🔴 24.9ms -8.4% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage 🟢 2.1ms 🟢 2.0ms -6.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator 🟢 0.2ms 🟢 0.2ms -14.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-nullable 🟢 0.4ms 🟢 0.4ms -7.6%
 ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime 🟢 2.0ms 🟢 1.8ms -9.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-openapi 🟢 2.3ms 🟢 2.3ms -1.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-private-usage 🟢 3.2ms 🟢 3.0ms -6.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-query-explode 🔴 28.3ms 🔴 26.3ms -7.0% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-response-body 🔴 33.9ms 🔴 32.3ms -4.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-rest-library-interfaces 🟢 0.1ms 🟢 0.1ms -6.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch 🟢 7.8ms 🟢 7.3ms -6.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params 🟢 0.4ms 🟢 0.4ms -7.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator 🟢 0.1ms 🟢 0.1ms -12.5%
 ↳ linter/@azure-tools/typespec-azure-core/no-unknown 🟢 0.4ms 🟢 0.3ms -4.1%
 ↳ linter/@azure-tools/typespec-azure-core/no-unnamed-union 🟢 0.8ms 🟢 0.8ms -1.7%
 ↳ linter/@azure-tools/typespec-azure-core/operation-missing-api-version 🟢 0.4ms 🟢 0.4ms -0.2%
 ↳ linter/@azure-tools/typespec-azure-core/request-body-problem 🟢 0.5ms 🟢 0.4ms -2.4%
 ↳ linter/@azure-tools/typespec-azure-core/require-versioned 🟢 0.1ms 🟢 0.1ms +0.2%
 ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem 🔴 33.2ms 🔴 30.5ms -8.3% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body 🟢 0.7ms 🟢 0.7ms -6.9%
 ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model 🟢 0.5ms 🟢 0.4ms -6.3%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-names 🟢 7.7ms 🟢 7.1ms -8.6%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-operations 🟢 0.3ms 🟢 0.3ms -2.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-child-resources 🔴 21.7ms 🔴 22.2ms +2.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-lifecycle-operations 🟢 0.3ms 🟢 0.3ms -2.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version 🟡 12.3ms 🟡 11.4ms -6.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key 🟢 0.2ms 🟢 0.2ms -11.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage 🟢 0.1ms 🟢 0.1ms -7.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes 🟢 5.0ms 🟢 5.1ms +1.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts 🟡 17.2ms 🟡 16.0ms -7.3% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record 🟢 0.6ms 🟢 0.6ms -6.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes 🟢 1.4ms 🟢 1.2ms -13.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes 🟢 0.2ms 🟢 0.2ms -2.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment 🟢 0.5ms 🟢 0.5ms +3.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property 🟢 0.4ms 🟢 0.4ms -8.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator 🟢 0.1ms 🟢 0.1ms -1.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb 🟢 0.2ms 🟢 0.2ms +1.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property 🟢 0.3ms 🟢 0.2ms -11.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format 🟢 0.2ms 🟢 0.2ms -2.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars 🟢 0.5ms 🟢 0.4ms -13.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern 🟢 0.1ms 🟢 0.1ms -9.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation 🟢 0.6ms 🟢 0.5ms -3.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response 🟢 9.1ms 🟢 8.7ms -4.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch 🟢 0.8ms 🟢 0.9ms +4.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars 🟢 0.4ms 🟢 0.4ms -2.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state 🟢 0.4ms 🟢 0.4ms -7.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels 🟢 0.2ms 🟢 0.2ms -12.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties 🟢 0.4ms 🟢 0.4ms -12.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation 🟢 0.1ms 🟢 0.1ms -11.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🔴 20.0ms 🟡 18.8ms -6.3% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint 🟢 0.1ms 🟢 0.1ms -12.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers 🟢 1.0ms 🟢 1.0ms -3.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model 🟢 0.3ms 🟢 0.2ms -11.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-override-props 🟢 0.3ms 🟢 0.3ms -3.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-reserved-resource-property 🟢 0.2ms 🟢 0.2ms -7.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation 🟢 0.5ms 🟢 0.4ms -11.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body 🔴 30.4ms 🔴 28.9ms -4.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope 🟢 0.4ms 🟢 0.4ms -5.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name 🟢 0.4ms 🟢 0.4ms -5.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop 🟢 5.4ms 🟢 5.4ms +0.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type 🟢 0.7ms 🟢 0.6ms -9.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/version-progression 🟢 0.3ms 🟢 0.3ms -7.3%
 ↳ linter/@azure-tools/typespec-client-generator-core/no-unnamed-types 🟢 0.0ms 🟢 2.9ms +100.0% 🔴
 ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict 🟢 2.3ms 🟢 2.2ms -6.9%
 ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix 🟢 1.7ms 🟢 1.6ms -7.1%
emit 🔴 6.13s 🔴 5.73s -6.4% 🟢
 ↳ emit/@Azure-Tools 🟢 0.0ms 🟢 0.0ms +0.0%
 ↳ emit/@azure-tools/typespec-autorest 🟢 127.0ms 🟢 122.3ms -3.7%
 ↳ emit/@azure-tools/typespec-python 🔴 2.28s 🔴 2.13s -6.8% 🟢
 ↳ emit/@typespec 🟢 0.0ms 🟢 0.0ms +0.0%
 ↳ emit/@typespec/http-client-js 🔴 578.5ms 🔴 546.7ms -5.5% 🟢
 ↳ emit/@typespec/openapi3 🟢 109.5ms 🟢 103.3ms -5.7% 🟢
 ↳ emit/@typespec/openapi3/compute 🟢 95.1ms 🟢 89.9ms -5.6% 🟢
 ↳ emit/@typespec/openapi3/write 🟢 14.0ms 🟢 13.0ms -7.5% 🟢

Averaged across 3 specs (azure-arm-resource-manager, azure-core-dataplane, azure-full).
Threshold: changes > ±5% are highlighted.
🟢 Fast · 🟡 Moderate (stages >200ms, rules >10ms) · 🔴 Slow (stages >400ms, rules >20ms)

iscai-msft and others added 4 commits July 14, 2026 14:48
…med-types

HTTP operation return types are typically anonymous unions of status-code
response envelopes (e.g. `ArmResponse<T> | ErrorResponse`). Clients only surface
the response body, never the envelope union, so flagging these produced many
false positives on real Azure specs. Exempt a return union when every non-null
variant is an HTTP envelope model or an @error model, while still descending into
variants to catch anonymous body types. Genuine anonymous body unions in the
return position (e.g. `"red" | "green"`) are still flagged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9d95a624-b5f5-4e82-a4b2-f08a5c301ade
Replace the structural return-type heuristic (which guessed whether a return
union was a status-code envelope via isHttpEnvelope/isErrorModel) with resolving
the actual HTTP responses via getHttpOperation and walking each response body.
This is the true client surface: response metadata (status codes, headers) is
stripped, so envelope unions like `ArmResponse<T> | ErrorResponse` never appear
and are not flagged, while genuine anonymous body types/unions are still caught.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9d95a624-b5f5-4e82-a4b2-f08a5c301ade
Replace the no-unnamed-union rule in @azure-tools/typespec-azure-core with
a broader no-unnamed-types rule that also flags anonymous models. The new rule
walks the type graph starting from user operations to detect anonymous types
on the client surface.

The TCGC no-unnamed-types rule is disabled in rulesets in favor of this
azure-core rule.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2777a16e-f173-48dd-962f-82b1b2bf6ed2
@microsoft-github-policy-service microsoft-github-policy-service Bot added the lib:azure-core Issues for @azure-tools/typespec-azure-core library label Jul 16, 2026
…vior

- Delete the TCGC no-unnamed-types rule entirely (source, tests, docs)
- Update azure-core no-unnamed-types to use the same union-flagging behavior
  as the old no-unnamed-union (flags all unnamed unions, not just those
  reachable from operations)
- Models are still only flagged when reachable from operations
- Remove TCGC rule from rulesets

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2777a16e-f173-48dd-962f-82b1b2bf6ed2
Comment thread packages/typespec-azure-core/src/rules/no-unnamed-types.ts Outdated
iscai-msft and others added 2 commits July 17, 2026 13:08
…odels

Uses the same include/exclude approach as unions — collect all anonymous
models in the visitor, exclude HTTP envelopes and stdlib types, then
report at exit. No custom navigateProgram walk needed.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2777a16e-f173-48dd-962f-82b1b2bf6ed2
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2777a16e-f173-48dd-962f-82b1b2bf6ed2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

int:azure-specs Run integration tests against azure-rest-api-specs lib:azure-core Issues for @azure-tools/typespec-azure-core library lib:tcgc Issues for @azure-tools/typespec-client-generator-core library linter Issues related to linter rules meta:website TypeSpec.io updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants