Skip to content

Add arm-no-replace-inherited-props linting rule#4384

Draft
Copilot wants to merge 12 commits into
mainfrom
copilot/add-arm-no-replace-inherited-props-linting-rule
Draft

Add arm-no-replace-inherited-props linting rule#4384
Copilot wants to merge 12 commits into
mainfrom
copilot/add-arm-no-replace-inherited-props-linting-rule

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 6, 2026

Redefining a property already declared on a base model is an Azure API anti-pattern and currently crashes the breaking-change tool (see azure-rest-api-specs#42903). This PR adds a new ARM linter rule to flag the pattern at design time.

Changes

  • New rule arm-no-replace-inherited-props (packages/typespec-azure-resource-manager/src/rules/arm-no-replace-inherited-props.ts)
    • Walks the baseModel chain and emits a warning for any property in the current model whose name also appears in any ancestor.
    • Allows overriding when both the inherited property and the overriding property reduce to the same scalar family (string, numeric, or boolean). The scalar family is computed by walking baseScalar chains, classifying enum members by value type, reducing unions via the getUnionAsEnum helper from @azure-tools/typespec-azure-core, reducing named union variants to their underlying type, and treating string/numeric/boolean literals as their underlying scalar. This naturally covers:
      • string overridden by string, by a scalar that extends string, by a string literal, by a string-valued enum, or by an open or closed string union.
      • A scalar / union / enum inherited from an ancestor overridden by a specific value of the scalar, a specific variant of the union, or a specific element of the enum (e.g. string"foo", int3212, "foo" | "bar""foo", named open union PropTypePropType.Foo).
      • The ARM resource name property (string ↔ string).
      • @discriminator properties overridden with a string literal in derived models.
    • No special-case logic is required for name or @discriminator; both fall out of the scalar-compatibility rule.
    • Diagnostic message: The property '${propertyName}' is also defined in the base model. Redefining inherited properties can cause problems with OpenAPI tooling and some language representations of the models.
  • Registration in src/linter.ts (included in the all ruleset).
  • Enabled in the shared resource-manager ruleset (packages/typespec-azure-rulesets/src/rulesets/resource-manager.ts).
  • Tests (14 cases) covering: clean inheritance, model-typed override (warns), transitive model-typed override (warns), and allowed cases for string→string, string→derived scalar, string→closed string union, string→open string union, numeric→numeric, ARM resource name, discriminator literal override, string→string literal value, int32→numeric literal value, anonymous closed string union→specific variant, and named open string union→named variant.
  • Docs: new rule page describing the scalar-compatibility behaviour, plus regenerated linter.md reference and package README.md.
  • Changeset under .chronus/changes/ covering both @azure-tools/typespec-azure-resource-manager and @azure-tools/typespec-azure-rulesets.

Example

@armProviderNamespace
namespace MyService;

@discriminator("kind")
model Pet {
  kind: string;
  weight: int32;
}

model Cat extends Pet {
  kind: "cat";    // OK — string and string literal are compatible scalars
  weight: int32;  // OK — same numeric scalar family
}

model Inner { a: string; }
model Base { nested: Inner; }
model Child extends Base {
  nested: Inner;  // ⚠ arm-no-replace-inherited-props (non-scalar override)
}

@microsoft-github-policy-service microsoft-github-policy-service Bot added lib:azure-resource-manager Issues for @azure-tools/typespec-azure-core library meta:website TypeSpec.io updates labels May 6, 2026
Copilot AI changed the title [WIP] Add ARM linting rule to prevent repeating inherited properties Add arm-no-replace-inherited-props linting rule May 6, 2026
Copilot AI requested a review from markcowl May 6, 2026 02:29
Copy link
Copy Markdown
Member

@markcowl markcowl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a merge conflict. Pull the latest from main, resolve the conflict, ensure all properties are correctly formatted and all tests pass and that only the chnages associated with this PR are in the PR diff

…place-inherited-props-linting-rule

# Conflicts:
#	website/src/content/docs/docs/libraries/azure-resource-manager/reference/linter.md

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 7, 2026

There is a merge conflict. Pull the latest from main, resolve the conflict, ensure all properties are correctly formatted and all tests pass and that only the chnages associated with this PR are in ...

Merged latest main and resolved the conflict in the auto-generated website/.../reference/linter.md (took main's link-format change and re-ran regen-docs to add the new rule entry). Also enabled the new rule in packages/typespec-azure-rulesets/src/rulesets/resource-manager.ts. Verified git diff origin/main shows only the 8 files associated with this PR. Targeted tests pass (147 ARM rule tests + 3 rulesets tests) and pnpm format is clean. Done in 49acb48.

Copilot AI requested a review from markcowl May 7, 2026 19:27
@markcowl markcowl added the int:azure-specs Run integration tests against azure-rest-api-specs label May 7, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

⚡ Benchmark Results

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

Metric Baseline Current Change
total 🔴 710.3ms 🔴 802.8ms +13.0% 🔴
loader 🟢 136.0ms 🟢 165.1ms +21.3% 🔴
checker 🟢 166.7ms 🟢 189.4ms +13.6% 🔴
linter 🟢 115.9ms 🟢 136.1ms +17.5% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🟡 16.1ms 🔴 20.1ms +24.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-query-explode 🟡 16.7ms 🔴 20.4ms +21.9% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-response-body 🔴 20.7ms 🔴 24.7ms +19.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem 🟡 19.4ms 🔴 22.5ms +16.1% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🟡 12.0ms 🟡 15.4ms +28.7% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body 🟡 18.5ms 🔴 22.2ms +20.2% 🔴
emit 🟡 230.8ms 🟡 249.1ms +7.9% 🔴
 ↳ emit/@azure-tools/typespec-autorest 🟢 143.5ms 🟢 156.0ms +8.7% 🔴
 ↳ emit/@typespec/openapi3 🟢 129.6ms 🟢 138.3ms +6.7% 🔴
 ↳ emit/@typespec/openapi3/compute 🟢 114.3ms 🟢 124.6ms +9.0% 🔴
Full details – comparing 583891c vs baseline 86cdf59
Metric Baseline Current Change
total 🔴 710.3ms 🔴 802.8ms +13.0% 🔴
loader 🟢 136.0ms 🟢 165.1ms +21.3% 🔴
resolver 🟢 15.9ms 🟢 16.6ms +4.3%
checker 🟢 166.7ms 🟢 189.4ms +13.6% 🔴
validation 🟢 39.6ms 🟢 41.2ms +4.0%
 ↳ validation/@azure-tools/typespec-azure-core 🟢 5.4ms 🟢 6.4ms +17.7%
 ↳ validation/@typespec/http 🟢 4.8ms 🟢 5.4ms +12.4%
 ↳ validation/@typespec/rest 🟢 0.5ms 🟢 0.5ms +8.3%
 ↳ validation/@typespec/versioning 🔴 27.0ms 🔴 26.9ms -0.3%
 ↳ validation/compiler 🟢 1.4ms 🟢 1.4ms -2.3%
linter 🟢 115.9ms 🟢 136.1ms +17.5% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/auth-required 🟢 0.0ms 🟢 0.0ms +3.5%
 ↳ linter/@azure-tools/typespec-azure-core/bad-record-type 🟢 0.2ms 🟢 0.2ms -2.0%
 ↳ linter/@azure-tools/typespec-azure-core/byos 🟢 5.2ms 🟢 6.0ms +15.4%
 ↳ linter/@azure-tools/typespec-azure-core/casing-style 🟢 0.5ms 🟢 0.6ms +4.8%
 ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance 🟢 0.1ms 🟢 0.1ms -4.5%
 ↳ linter/@azure-tools/typespec-azure-core/documentation-required 🟢 0.7ms 🟢 0.7ms -4.2%
 ↳ linter/@azure-tools/typespec-azure-core/friendly-name 🟢 0.5ms 🟢 0.6ms +4.1%
 ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required 🟢 0.1ms 🟢 0.1ms +1.5%
 ↳ linter/@azure-tools/typespec-azure-core/known-encoding 🟢 0.2ms 🟢 0.2ms -9.1%
 ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required 🟢 0.3ms 🟢 0.3ms +11.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch 🟢 0.2ms 🟢 0.2ms +1.9%
 ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union 🟢 0.2ms 🟢 0.2ms +4.9%
 ↳ linter/@azure-tools/typespec-azure-core/no-enum 🟢 0.0ms 🟢 0.0ms +8.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes 🟢 0.1ms 🟢 0.1ms +14.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops 🟢 0.1ms 🟢 0.1ms +6.6%
 ↳ linter/@azure-tools/typespec-azure-core/no-format 🟢 0.4ms 🟢 0.4ms +0.1%
 ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric 🟢 0.4ms 🟢 0.3ms -7.5%
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🟡 16.1ms 🔴 20.1ms +24.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage 🟢 1.0ms 🟢 1.0ms +5.1%
 ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator 🟢 0.1ms 🟢 0.1ms -5.9%
 ↳ linter/@azure-tools/typespec-azure-core/no-nullable 🟢 0.2ms 🟢 0.2ms +1.9%
 ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime 🟢 1.2ms 🟢 1.2ms +5.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-openapi 🟢 1.7ms 🟢 1.7ms +1.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-private-usage 🟢 1.7ms 🟢 1.7ms +3.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-query-explode 🟡 16.7ms 🔴 20.4ms +21.9% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-response-body 🔴 20.7ms 🔴 24.7ms +19.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-rest-library-interfaces 🟢 0.0ms 🟢 0.0ms +4.4%
 ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch 🟢 4.7ms 🟢 5.7ms +21.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params 🟢 0.2ms 🟢 0.2ms +11.1%
 ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator 🟢 0.0ms 🟢 0.0ms -3.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-unknown 🟢 0.1ms 🟢 0.2ms +12.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-unnamed-union 🟢 0.3ms 🟢 0.3ms +1.5%
 ↳ linter/@azure-tools/typespec-azure-core/operation-missing-api-version 🟢 0.2ms 🟢 0.1ms -8.6%
 ↳ linter/@azure-tools/typespec-azure-core/request-body-problem 🟢 0.2ms 🟢 0.2ms -4.6%
 ↳ linter/@azure-tools/typespec-azure-core/require-versioned 🟢 0.0ms 🟢 0.0ms -4.5%
 ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem 🟡 19.4ms 🔴 22.5ms +16.1% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body 🟢 0.3ms 🟢 0.3ms +16.3%
 ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model 🟢 0.2ms 🟢 0.2ms +0.5%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-names 🟢 4.3ms 🟢 5.3ms +21.9%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-operations 🟢 0.1ms 🟢 0.1ms +17.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version 🟢 3.5ms 🟢 4.3ms +23.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key 🟢 0.1ms 🟢 0.1ms +21.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage 🟢 0.1ms 🟢 0.1ms +6.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes 🟢 4.6ms 🟢 5.6ms +21.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts 🟢 4.0ms 🟢 4.9ms +24.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record 🟢 0.3ms 🟢 0.3ms +1.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-replace-inherited-props 🟢 0.0ms 🟢 0.1ms +100.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes 🟢 0.4ms 🟢 0.5ms +35.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes 🟢 0.0ms 🟢 0.0ms +6.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment 🟢 0.2ms 🟢 0.2ms +10.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property 🟢 0.1ms 🟢 0.1ms +16.0%
 ↳ 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.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property 🟢 0.1ms 🟢 0.1ms +10.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format 🟢 0.0ms 🟢 0.0ms +8.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars 🟢 0.2ms 🟢 0.2ms +21.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern 🟢 0.0ms 🟢 0.0ms -5.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation 🟢 0.1ms 🟢 0.2ms +3.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response 🟢 4.7ms 🟢 5.5ms +16.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch 🟢 0.3ms 🟢 0.3ms +14.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars 🟢 0.2ms 🟢 0.2ms +12.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state 🟢 0.1ms 🟢 0.1ms +13.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels 🟢 0.1ms 🟢 0.1ms +12.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties 🟢 0.1ms 🟢 0.1ms +13.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation 🟢 0.0ms 🟢 0.0ms +4.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🟡 12.0ms 🟡 15.4ms +28.7% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint 🟢 0.0ms 🟢 0.0ms +10.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers 🟢 0.2ms 🟢 0.3ms +12.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model 🟢 0.1ms 🟢 0.1ms +12.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation 🟢 0.1ms 🟢 0.2ms +18.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body 🟡 18.5ms 🔴 22.2ms +20.2% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope 🟢 0.1ms 🟢 0.1ms +13.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name 🟢 0.1ms 🟢 0.1ms +7.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop 🟢 2.0ms 🟢 2.1ms +5.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type 🟢 0.3ms 🟢 0.4ms +10.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/version-progression 🟢 0.0ms 🟢 0.0ms -3.8%
 ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict 🟢 0.9ms 🟢 1.0ms +7.5%
 ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix 🟢 0.2ms 🟢 0.2ms -3.4%
emit 🟡 230.8ms 🟡 249.1ms +7.9% 🔴
 ↳ emit/@azure-tools/typespec-autorest 🟢 143.5ms 🟢 156.0ms +8.7% 🔴
 ↳ emit/@typespec/openapi3 🟢 129.6ms 🟢 138.3ms +6.7% 🔴
 ↳ emit/@typespec/openapi3/compute 🟢 114.3ms 🟢 124.6ms +9.0% 🔴
 ↳ emit/@typespec/openapi3/write 🟢 14.4ms 🟢 13.7ms -4.8%

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)

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 7, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@azure-tools/typespec-azure-resource-manager@4384
npm i https://pkg.pr.new/@azure-tools/typespec-azure-rulesets@4384

commit: bf16a95

Copy link
Copy Markdown
Member

@markcowl markcowl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update the changeset to include your change to the rulesets.

Pull the latest from main, ensure all files are well formatted and only the changes associated with this PR are in the PR diff.

Copilot AI and others added 2 commits May 7, 2026 21:56
…place-inherited-props-linting-rule

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 7, 2026

Update the changeset to include your change to the rulesets.

Pull the latest from main, ensure all files are well formatted and only the changes associated with this PR are in the PR diff.

Updated the changeset to include @azure-tools/typespec-azure-rulesets (6d60f84). Also pulled latest from main (clean merge, no conflicts) and verified pnpm format is clean. git diff origin/main --stat shows only the 8 files associated with this PR.

Copilot AI requested a review from markcowl May 7, 2026 22:00
Copy link
Copy Markdown
Member

@markcowl markcowl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Please follow the instuctio0ns in the comment

Copilot AI and others added 2 commits May 12, 2026 23:54
…place-inherited-props-linting-rule

# Conflicts:
#	packages/typespec-azure-resource-manager/README.md
#	packages/typespec-azure-resource-manager/src/linter.ts
#	packages/typespec-azure-rulesets/src/rulesets/resource-manager.ts
#	website/src/content/docs/docs/libraries/azure-resource-manager/reference/linter.md

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 13, 2026

@copilot Please follow the instuctio0ns in the comment

Done — addressed the review feedback in 5180f69. Details in the inline reply.

Copilot AI requested a review from markcowl May 13, 2026 00:11
}
case "EnumMember":
return typeof type.value === "number" ? "numeric" : "string";
case "Union": {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use this helper to determine if a union is an open or closed enumeration over a string or numeric type: https://github.com/Azure/typespec-azure/blob/main/packages/typespec-azure-core/src/helpers/union-enums.ts#L83

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored in 826590c to use getUnionAsEnum from @azure-tools/typespec-azure-core for the Union case — it returns either a string- or number-kind enum (open or closed), which collapses directly into the scalar-family check.

@markcowl
Copy link
Copy Markdown
Member

/azp run typespec-azure - PR Tools

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@azure-sdk
Copy link
Copy Markdown
Collaborator

All changed packages have been documented.

  • @azure-tools/typespec-azure-resource-manager
  • @azure-tools/typespec-azure-rulesets
Show changes

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

Add new linting rule arm-no-replace-inherited-props that warns when a model redefines a property that is already defined in one of its base models. The 'name' property of an ARM resource and properties redefined as part of a model marked with @discriminator are not flagged by this rule.

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

Add new linting rule arm-no-replace-inherited-props that warns when a model redefines a property that is already defined in one of its base models. The 'name' property of an ARM resource and properties redefined as part of a model marked with @discriminator are not flagged by this rule.

@azure-sdk
Copy link
Copy Markdown
Collaborator

You can try these changes here

🛝 Playground 🌐 Website

Copy link
Copy Markdown
Member

@markcowl markcowl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot

Pull the latest from main, make these test changes, make any implementation changes required to make these pass, ensure that all files are correctly formatted and all tests pass. Ensure that only the changes associated with this PR are in the PR diff.

import { Tester } from "#test/tester.js";
import {
createLinterRuleTester,
LinterRuleTester,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add tests that allow overriding a scalar type, string union, or enum type inherited from an ancestor with a specific value of the scalar type, a specific variant of the union, or a specific element of the enum.

For example:

// string
model Parent {
  prop: string;
}

model Child extends Parent {
  prop: "foo";
}

// int32
model Parent {
  prop: int32;
}

model Child extends Parent {
  prop: 12;
}

// anonymous closed string-typed union
model Parent {
  prop: "foo" | "bar";
}

model Child extends Parent {
  prop: "foo";
}

// open union with named variants

union PropType {
  Foo: "foo",
  Bar: "bar",
  string
}
model Parent {
  prop: PropType;
}

model Child extends Parent {
  prop: PropType.Foo;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added all four test cases in 826590c (string → "foo", int32 → 12, "foo" | "bar""foo", and named open union PropTypePropType.Foo). The implementation needed one small addition — handling the UnionVariant kind in getScalarFamily so that PropType.Foo (a named variant reference) reduces to its underlying string type. All 14 rule tests and 170 ARM rule tests pass.

Copilot AI and others added 2 commits May 14, 2026 20:19
…place-inherited-props-linting-rule

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 14, 2026

@copilot

Pull the latest from main, make these test changes, make any implementation changes required to make these pass, ensure that all files are correctly formatted and all tests pass. Ensure t...

Done in 826590c — pulled latest from main, added the 4 new test cases, made the small implementation change required (UnionVariant handling in the scalar-family reducer), and confirmed pnpm format is clean. All 170 ARM rule tests pass and the PR diff still contains only the 8 PR-related files.

Copilot AI requested a review from markcowl May 14, 2026 20:29
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-resource-manager Issues for @azure-tools/typespec-azure-core library meta:website TypeSpec.io updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[linting-rules]: Disallow repeating inherited properties in child types

3 participants