diff --git a/.chronus/changes/rejc2-support-serialization-of-object-examples-on-unions-2024-11-6-14-7-58.md b/.chronus/changes/rejc2-support-serialization-of-object-examples-on-unions-2024-11-6-14-7-58.md new file mode 100644 index 0000000000..e0b9e074bb --- /dev/null +++ b/.chronus/changes/rejc2-support-serialization-of-object-examples-on-unions-2024-11-6-14-7-58.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/compiler" +--- + +Fixed serialization of object examples on unions \ No newline at end of file diff --git a/packages/compiler/src/lib/examples.ts b/packages/compiler/src/lib/examples.ts index 241844ae56..0c697fc35c 100644 --- a/packages/compiler/src/lib/examples.ts +++ b/packages/compiler/src/lib/examples.ts @@ -72,11 +72,12 @@ function resolveUnions(program: Program, value: ObjectValue, type: Type): Type | if (type.kind !== "Union") { return type; } + const exactValueType = program.checker.getValueExactType(value); for (const variant of type.variants.values()) { if ( ignoreDiagnostics( program.checker.isTypeAssignableTo( - value.type.projectionBase ?? value.type, + exactValueType ?? value.type.projectionBase ?? value.type, variant.type.projectionBase ?? variant.type, value, ), diff --git a/packages/compiler/test/decorators/examples.test.ts b/packages/compiler/test/decorators/examples.test.ts index 3a50bb5e85..dae845c227 100644 --- a/packages/compiler/test/decorators/examples.test.ts +++ b/packages/compiler/test/decorators/examples.test.ts @@ -173,7 +173,7 @@ describe("@example", () => { }); describe("union", () => { - it("valid", async () => { + it("valid for union member reference", async () => { const { program, examples, target } = await getExamplesFor(` @example(test.a) @test union test {a: "a", b: "b"} @@ -182,6 +182,30 @@ describe("@example", () => { expect(serializeValueAsJson(program, examples[0].value, target)).toEqual("a"); }); + it("valid for object value", async () => { + const { program, examples, target } = await getExamplesFor(` + model A { + type: "a"; + a: string; + } + model B { + type: "b"; + b: numeric; + } + + @example(#{ + type: "a", + a: "a string", + }) + @test union test {a: A, b: B} + `); + expect(examples).toHaveLength(1); + expect(serializeValueAsJson(program, examples[0].value, target)).toEqual({ + type: "a", + a: "a string", + }); + }); + it("emit diagnostic for unassignable value", async () => { const diagnostics = await diagnoseCode(` @example(1)