Skip to content

Remove use of implicit optionality#4388

Draft
timotheeguerin wants to merge 4 commits into
Azure:mainfrom
timotheeguerin:fix/remove-implicit-optionality
Draft

Remove use of implicit optionality#4388
timotheeguerin wants to merge 4 commits into
Azure:mainfrom
timotheeguerin:fix/remove-implicit-optionality

Conversation

@timotheeguerin
Copy link
Copy Markdown
Member

@timotheeguerin timotheeguerin commented May 6, 2026

fix #4371

@microsoft-github-policy-service microsoft-github-policy-service Bot added lib:azure-core Issues for @azure-tools/typespec-azure-core library lib:azure-resource-manager Issues for @azure-tools/typespec-azure-core library lib:azure-http-specs For issues/prs related to the @azure-tools/typespec-azure-http-specs package labels May 6, 2026
@timotheeguerin timotheeguerin added the int:azure-specs Run integration tests against azure-rest-api-specs label May 6, 2026
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 6, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@azure-tools/azure-http-specs@4388
npm i https://pkg.pr.new/@azure-tools/typespec-azure-core@4388
npm i https://pkg.pr.new/@azure-tools/typespec-azure-resource-manager@4388

commit: 1cb3b50

@azure-sdk
Copy link
Copy Markdown
Collaborator

azure-sdk commented May 6, 2026

All changed packages have been documented.

  • @azure-tools/azure-http-specs
  • @azure-tools/typespec-azure-core
  • @azure-tools/typespec-azure-resource-manager
Show changes

@azure-tools/azure-http-specs - internal ✏️

Remove use of implicit optionality which was a noop in one operation

@azure-tools/typespec-azure-resource-manager - breaking ✏️

Removed implicitOptionality: true from the @patch decorator on the following operation templates:,> ,> - ArmTagsPatchAsync,> - ArmResourcePatchAsync,> - ArmTagsPatchSync,> - ArmResourcePatchSync,> - ResourceUpdateSync.update (in ResourceUpdateSync interface),> ,> Previously, these templates used @patch(#{ implicitOptionality: true }) which caused all properties in the PATCH request body to be implicitly treated as optional, regardless of how they were declared in the model. This behavior is now removed — properties will retain their declared optionality.,> ,> #### Migration,> ,> If you use these ARM operation templates, the PATCH body will no longer implicitly make all properties optional. In most cases, ARM resources already use ResourceUpdateModel<Resource, Properties> which produces the correct optional property envelope — if so, no changes are needed.,> ,> If you have a custom patch body that relied on implicit optionality, explicitly mark properties as optional:,> ,> Before (implicit optionality made all properties optional automatically):,> ,> tsp,> model MyResourceProperties {,> displayName: string;,> config: MyConfig;,> },> ,> ,> After (explicitly declare optional properties for update):,> ,> tsp,> model MyResourceUpdateProperties {,> displayName?: string;,> config?: MyConfig;,> },> ,> ,> Or continue using ResourceUpdateModel<Resource, Properties> which already handles this transformation for standard ARM resource patterns.

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

Removed implicitOptionality: true from the @patch decorator on the following operation templates:,> ,> - ResourceCreateOrUpdate,> - LongRunningResourceCreateOrUpdate,> - ResourceUpdate,> ,> Previously, these templates used @patch(#{ implicitOptionality: true }) which caused all properties in the PATCH request body to be implicitly treated as optional, regardless of how they were declared in the model. This behavior is now removed — properties will retain their declared optionality.,> ,> #### Migration,> ,> If your service relies on all properties being optional in the PATCH body, you need to explicitly mark them as optional in your model:,> ,> Before (implicit optionality made all properties optional automatically):,> ,> tsp,> model Widget {,> name: string;,> color: string;,> },> ,> ,> After (explicitly declare optional properties):,> ,> tsp,> model WidgetUpdate {,> name?: string;,> color?: string;,> },> ,> ,> Alternatively, you can use the ResourceUpdateModel template or OptionalProperties utility to derive an all-optional version of your model for PATCH operations. If you were already using ResourceUpdateModel<Resource> or manually defining optional properties in your update model, no changes are needed.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

⚡ Benchmark Results

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

Metric Baseline Current Change
 ↳ linter/@azure-tools/typespec-azure-core/known-encoding 🟢 0.2ms 🟢 0.3ms +6.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-openapi 🟢 1.9ms 🟢 2.1ms +9.3% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem 🔴 24.0ms 🔴 30.0ms +25.1% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage 🟢 0.1ms 🟢 0.3ms +246.9% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes 🟢 0.0ms 🟢 0.0ms +16.7% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator 🟢 0.0ms 🟢 0.0ms +9.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars 🟢 0.3ms 🟢 0.3ms +6.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern 🟢 0.0ms 🟢 0.0ms +25.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state 🟢 0.1ms 🟢 0.1ms +13.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation 🟢 0.0ms 🟢 0.0ms +18.8% 🔴
Full details – comparing 07c33cf vs baseline a90e3a0
Metric Baseline Current Change
total 🔴 837.6ms 🔴 822.0ms -1.9%
loader 🟢 162.4ms 🟢 160.4ms -1.2%
resolver 🟢 18.1ms 🟢 17.4ms -3.9%
checker 🟡 204.3ms 🟢 198.2ms -3.0%
validation 🟢 43.2ms 🟢 42.7ms -1.2%
 ↳ validation/@azure-tools/typespec-azure-core 🟢 7.0ms 🟢 6.8ms -1.8%
 ↳ validation/@typespec/http 🟢 7.0ms 🟢 6.8ms -3.9%
 ↳ validation/@typespec/rest 🟢 0.5ms 🟢 0.5ms +2.6%
 ↳ validation/@typespec/versioning 🔴 27.1ms 🔴 27.0ms -0.4%
 ↳ validation/compiler 🟢 1.6ms 🟢 1.6ms -2.0%
linter 🟢 150.6ms 🟢 151.4ms +0.5%
 ↳ linter/@azure-tools/typespec-azure-core/auth-required 🟢 0.0ms 🟢 0.0ms -10.3% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/bad-record-type 🟢 0.2ms 🟢 0.2ms -6.4% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/byos 🟢 9.9ms 🟢 6.4ms -35.6% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/casing-style 🟢 0.6ms 🟢 0.6ms -5.4% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance 🟢 0.1ms 🟢 0.1ms +0.6%
 ↳ linter/@azure-tools/typespec-azure-core/documentation-required 🟢 0.8ms 🟢 0.8ms -3.6%
 ↳ linter/@azure-tools/typespec-azure-core/friendly-name 🟢 0.7ms 🟢 0.7ms -1.2%
 ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required 🟢 0.2ms 🟢 0.2ms -2.9%
 ↳ linter/@azure-tools/typespec-azure-core/known-encoding 🟢 0.2ms 🟢 0.3ms +6.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required 🟢 0.3ms 🟢 0.3ms -2.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch 🟢 0.2ms 🟢 0.2ms -3.5%
 ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union 🟢 0.3ms 🟢 0.3ms -2.9%
 ↳ linter/@azure-tools/typespec-azure-core/no-enum 🟢 0.0ms 🟢 0.0ms -3.1%
 ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes 🟢 0.1ms 🟢 0.1ms -1.6%
 ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops 🟢 0.1ms 🟢 0.1ms +0.5%
 ↳ linter/@azure-tools/typespec-azure-core/no-format 🟢 0.5ms 🟢 0.5ms -5.6% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric 🟢 0.4ms 🟢 0.4ms -1.5%
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🔴 21.6ms 🔴 21.5ms -0.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage 🟢 1.1ms 🟢 1.1ms -0.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator 🟢 0.1ms 🟢 0.1ms -0.5%
 ↳ linter/@azure-tools/typespec-azure-core/no-nullable 🟢 0.2ms 🟢 0.2ms -2.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime 🟢 1.3ms 🟢 1.3ms -2.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-openapi 🟢 1.9ms 🟢 2.1ms +9.3% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-private-usage 🟢 1.8ms 🟢 1.8ms -3.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-query-explode 🔴 21.4ms 🔴 20.6ms -3.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-response-body 🔴 23.5ms 🔴 23.5ms +0.1%
 ↳ linter/@azure-tools/typespec-azure-core/no-rest-library-interfaces 🟢 0.0ms 🟢 0.0ms -0.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch 🟢 6.2ms 🟢 5.8ms -6.0% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params 🟢 0.2ms 🟢 0.2ms +3.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator 🟢 0.1ms 🟢 0.0ms -6.2% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/no-unknown 🟢 0.2ms 🟢 0.2ms -1.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-unnamed-union 🟢 0.3ms 🟢 0.3ms -5.5% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/operation-missing-api-version 🟢 0.2ms 🟢 0.2ms -8.0% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/request-body-problem 🟢 0.2ms 🟢 0.2ms -4.2%
 ↳ linter/@azure-tools/typespec-azure-core/require-versioned 🟢 0.0ms 🟢 0.0ms -3.5%
 ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem 🔴 24.0ms 🔴 30.0ms +25.1% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body 🟢 0.3ms 🟢 0.3ms -6.0% 🟢
 ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model 🟢 0.3ms 🟢 0.3ms +3.7%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-names 🟢 5.3ms 🟢 5.3ms -0.1%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-operations 🟢 0.1ms 🟢 0.1ms -8.7% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version 🟢 5.6ms 🟢 5.7ms +2.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key 🟢 0.1ms 🟢 0.1ms -7.6% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage 🟢 0.1ms 🟢 0.3ms +246.9% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes 🟢 7.5ms 🟢 7.1ms -4.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts 🟢 6.1ms 🟢 6.0ms -2.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record 🟢 0.4ms 🟢 0.4ms -5.9% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes 🟢 0.7ms 🟢 0.7ms -4.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes 🟢 0.0ms 🟢 0.0ms +16.7% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment 🟢 0.2ms 🟢 0.2ms -1.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property 🟢 0.1ms 🟢 0.1ms -3.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator 🟢 0.0ms 🟢 0.0ms +9.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb 🟢 0.1ms 🟢 0.1ms +2.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property 🟢 0.1ms 🟢 0.1ms +3.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format 🟢 0.1ms 🟢 0.1ms -9.7% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars 🟢 0.3ms 🟢 0.3ms +6.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern 🟢 0.0ms 🟢 0.0ms +25.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation 🟢 0.2ms 🟢 0.2ms +1.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response 🟢 6.3ms 🟢 6.2ms -0.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch 🟢 0.4ms 🟢 0.4ms -2.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars 🟢 0.2ms 🟢 0.2ms -1.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state 🟢 0.1ms 🟢 0.1ms +13.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels 🟢 0.1ms 🟢 0.1ms +3.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties 🟢 0.2ms 🟢 0.2ms +0.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation 🟢 0.0ms 🟢 0.0ms +18.8% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🟡 19.4ms 🟡 18.9ms -2.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint 🟢 0.0ms 🟢 0.0ms +3.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers 🟢 0.3ms 🟢 0.3ms -5.2% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model 🟢 0.1ms 🟢 0.1ms -4.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation 🟢 0.2ms 🟢 0.2ms -2.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body 🔴 28.1ms 🔴 28.6ms +1.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope 🟢 0.1ms 🟢 0.2ms +4.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name 🟢 0.2ms 🟢 0.2ms -10.0% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop 🟢 2.6ms 🟢 2.6ms -0.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type 🟢 0.5ms 🟢 0.4ms -6.9% 🟢
 ↳ linter/@azure-tools/typespec-azure-resource-manager/version-progression 🟢 0.0ms 🟢 0.0ms -3.9%
 ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict 🟢 1.1ms 🟢 1.1ms -0.4%
 ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix 🟢 0.2ms 🟢 0.2ms -6.0% 🟢
emit 🟡 259.0ms 🟡 251.9ms -2.7%
 ↳ emit/@azure-tools/typespec-autorest 🟢 161.9ms 🟢 158.8ms -1.9%
 ↳ emit/@typespec/openapi3 🟢 145.4ms 🟢 139.4ms -4.1%
 ↳ emit/@typespec/openapi3/compute 🟢 130.3ms 🟢 123.6ms -5.1% 🟢
 ↳ emit/@typespec/openapi3/write 🟢 15.1ms 🟢 15.8ms +4.6%

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)

@azure-sdk
Copy link
Copy Markdown
Collaborator

azure-sdk commented May 6, 2026

You can try these changes here

🛝 Playground 🌐 Website

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:azure-http-specs For issues/prs related to the @azure-tools/typespec-azure-http-specs package lib:azure-resource-manager Issues for @azure-tools/typespec-azure-core library

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deprecate/retire ARM templates that use implicitOptionality: true

2 participants