diff --git a/.chronus/changes/fix-cs1763-1779128907.md b/.chronus/changes/fix-cs1763-1779128907.md new file mode 100644 index 00000000000..81b7fc8d1bb --- /dev/null +++ b/.chronus/changes/fix-cs1763-1779128907.md @@ -0,0 +1,9 @@ +--- +changeKind: fix +packages: + - "@typespec/http-server-csharp" +--- + +Fix invalid constructor generated for `@error` models with numeric literal properties + +When an `@error` model has a property with a numeric or floating-point literal type (e.g., `status: 404` or `retryAfter: 1.5`), the emitter now generates a correctly-typed constructor parameter (`int`/`double`) instead of `object`, which previously caused a CS1763 compiler error. diff --git a/packages/http-server-csharp/src/lib/service.ts b/packages/http-server-csharp/src/lib/service.ts index 3dd2b41015b..8e2b29b57e6 100644 --- a/packages/http-server-csharp/src/lib/service.ts +++ b/packages/http-server-csharp/src/lib/service.ts @@ -95,6 +95,7 @@ import { coalesceUnionTypes, ensureCSharpIdentifier, ensureCleanDirectory, + findNumericType, formatComment, getBusinessLogicCallParameters, getBusinessLogicDeclParameters, @@ -492,8 +493,12 @@ export async function $onEmit(context: EmitContext) } const type = getCSharpType(program, prop.type); + const typeName = + prop.type.kind === "Number" + ? findNumericType(prop.type)[0] + : (type?.type.name ?? "object"); properties.push( - `${type?.type.name} ${prop.name}${defaultValue ? ` = ${defaultValue}` : `${prop.optional ? " = default" : ""}`}`, + `${typeName} ${prop.name}${defaultValue ? ` = ${defaultValue}` : `${prop.optional ? " = default" : ""}`}`, ); body.push(`\t\t${propertyName} = ${prop.name};`); diff --git a/packages/http-server-csharp/test/generation.test.ts b/packages/http-server-csharp/test/generation.test.ts index ab3d989aedb..001e9b8e107 100644 --- a/packages/http-server-csharp/test/generation.test.ts +++ b/packages/http-server-csharp/test/generation.test.ts @@ -3206,6 +3206,43 @@ describe("emit correct code for `@error` models", () => { ], ); }); + it("emits correct constructor parameter type for numeric literal property", async () => { + await compileAndValidateSingleModel( + tester, + ` + @error + model NotFoundProblem { + title: string; + status: 404; + } + `, + "NotFoundProblem.cs", + [ + "public partial class NotFoundProblem : HttpServiceException {", + `public NotFoundProblem(string title, int status = 404) : base(400,`, + `value: new{title = title,status = status})`, + `public int Status { get; } = 404;`, + ], + ); + }); + it("emits correct constructor parameter type for float literal property", async () => { + await compileAndValidateSingleModel( + tester, + ` + @error + model RateLimitError { + message: string; + retryAfter: 1.5; + } + `, + "RateLimitError.cs", + [ + "public partial class RateLimitError : HttpServiceException {", + `public RateLimitError(string message, double retryAfter = 1.5) : base(400,`, + `public double RetryAfter { get; } = 1.5;`, + ], + ); + }); it("emit error constructor properties and defined in body", async () => { await compileAndValidateSingleModel( tester,