Skip to content

Commit

Permalink
Optional props cannot be assigned to required ones (#3290)
Browse files Browse the repository at this point in the history
fix #3267

---------

Co-authored-by: Brian Terlson <brian.terlson@microsoft.com>
  • Loading branch information
timotheeguerin and bterlson committed May 6, 2024
1 parent d8c26b1 commit 4b3489f
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: fix
packages:
- "@typespec/compiler"
---

Model with an optional property should not be satisfy a constraint with that property required. (`{foo?: string}` cannot be assigned to a constraint of `{foo: string}`)
12 changes: 12 additions & 0 deletions packages/compiler/src/core/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5785,6 +5785,18 @@ export function createChecker(program: Program): Checker {
} else {
remainingProperties.delete(prop.name);

if (sourceProperty.optional && !prop.optional) {
diagnostics.push(
createDiagnostic({
code: "property-required",
format: {
propName: prop.name,
targetType: getTypeName(target),
},
target: diagnosticTarget,
})
);
}
const [related, propDiagnostics] = isTypeAssignableToInternal(
sourceProperty.type,
prop.type,
Expand Down
6 changes: 6 additions & 0 deletions packages/compiler/src/core/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,12 @@ const diagnostics = {
withDetails: paramMessage`Type '${"sourceType"}' is not assignable to type '${"targetType"}'\n ${"details"}`,
},
},
"property-required": {
severity: "error",
messages: {
default: paramMessage`Property '${"propName"}' is required in type '${"targetType"}' but here is optional.`,
},
},
"no-prop": {
severity: "error",
messages: {
Expand Down
10 changes: 10 additions & 0 deletions packages/compiler/test/checker/relation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,16 @@ describe("compiler: checker: type relations", () => {
});
});

it("emit diagnostic when optional property is assigned to required", async () => {
await expectTypeNotAssignable(
{ source: `{foo?: string}`, target: `{foo: string}` },
{
code: "property-required",
message: "Property 'foo' is required in type '(anonymous model)' but here is optional.",
}
);
});

it("emit diagnostic when required property is missing", async () => {
await expectTypeNotAssignable(
{ source: `{foo: "abc"}`, target: `{foo: string, bar: string}` },
Expand Down

0 comments on commit 4b3489f

Please sign in to comment.