Skip to content

Add more descriptive message for @pattern decorator when applied to union type #7586

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@typespec/compiler"
---

Improved the error message for the `@pattern` decorator when applied to a `union` type. The new message is more descriptive and helps users understand how to correctly define string-compatible union types.
8 changes: 6 additions & 2 deletions packages/compiler/src/lib/decorators.ts
Original file line number Diff line number Diff line change
@@ -294,13 +294,17 @@ function validateTargetingAString(
target: Scalar | ModelProperty,
decoratorName: string,
) {
const valid = isTypeIn(getPropertyType(target), (x) => isStringType(context.program, x));
const propertyType = getPropertyType(target);
const valid = isTypeIn(propertyType, (x) => isStringType(context.program, x));
if (!valid) {
reportDiagnostic(context.program, {
code: "decorator-wrong-target",
format: {
decorator: decoratorName,
to: `type it is not a string`,
to:
propertyType.kind === "Union"
? `a union type that is not string compatible. The union must explicitly include a string type, and all union values should be strings. For example: union Test { string, "A", "B" }`
: `type it is not a string`,
},
target: context.decoratorTarget,
});
28 changes: 28 additions & 0 deletions packages/compiler/test/decorators/decorators.test.ts
Original file line number Diff line number Diff line change
@@ -272,6 +272,34 @@ describe("compiler: built-in decorators", () => {
});
});

it("emit diagnostic if pattern targe is a non-string union", async () => {
const diagnostics = await runner.diagnose(`
model Employee {
@pattern("^[a-zA-Z0-9-]{3,24}$")
name: Test;
}
union Test { 1, int32 }
`);

expectDiagnostics(diagnostics, {
code: "decorator-wrong-target",
message:
'Cannot apply @pattern decorator to a union type that is not string compatible. The union must explicitly include a string type, and all union values should be strings. For example: union Test { string, "A", "B" }',
});
});

it("allows string union on @pattern", async () => {
const diagnostics = await runner.diagnose(`
model Employee {
@pattern("^[a-zA-Z0-9-]{3,24}$")
name: Test;
}
union Test { "A", "B", string }
`);

expectDiagnosticEmpty(diagnostics);
});

it("emit diagnostic if pattern is not a valid RegEx", async () => {
const diagnostics = await runner.diagnose(`
model A {
Loading
Oops, something went wrong.