Description
When a single-member enum (e.g., enum Colors { green }) is used as a property type and @alternateType("green") is applied, the C# emitter generates a constant "green" instead of keeping the Colors enum type.
TypeSpec to reproduce
enum Colors {
green,
}
model EmployeeProperties {
@Azure.ClientGenerator.Core.alternateType("green")
favoriteColor: Colors;
}
Playground link
Expected behavior
The C# emitter should generate a struct named Colors (as an enum type). The type of favoriteColor should be Colors.
Actual behavior
The type of favoriteColor is generated as a constant "green" (a string literal), losing the Colors enum type entirely.
Root cause analysis
Investigation in Azure/azure-sdk-for-net#57771 found:
-
TCGC resolves the type incorrectly: When @alternateType("green") is applied to a property of type Colors (a single-member enum), TCGC resolves the alternate type as a string literal "green" (an SdkConstantType with kind: "constant", value: "green", valueType.kind: "string"), losing the reference to the Colors enum entirely. Without @alternateType, the single-member enum correctly emits as kind: "enum" with name: "Colors".
-
The C# emitter then handles the constant case: In type-converter.js fromSdkType(), the case "constant": branch:
- For optional properties with constants → converts to extensible enum (correct behavior)
- For required properties with constants → keeps as literal/constant (the buggy path)
The fix should likely be in the fromSdkType function in type-converter.ts (case "constant": branch) to check if the original property type was an enum and preserve that enum type instead of collapsing to a constant.
Alternatively, this could also be addressed in TCGC (@azure-tools/typespec-client-generator-core) so it does not resolve @alternateType("green") on an enum-typed property as a plain string constant.
Related issues
Description
When a single-member enum (e.g.,
enum Colors { green }) is used as a property type and@alternateType("green")is applied, the C# emitter generates a constant"green"instead of keeping theColorsenum type.TypeSpec to reproduce
Playground link
Expected behavior
The C# emitter should generate a struct named
Colors(as an enum type). The type offavoriteColorshould beColors.Actual behavior
The type of
favoriteColoris generated as a constant"green"(a string literal), losing theColorsenum type entirely.Root cause analysis
Investigation in Azure/azure-sdk-for-net#57771 found:
TCGC resolves the type incorrectly: When
@alternateType("green")is applied to a property of typeColors(a single-member enum), TCGC resolves the alternate type as a string literal"green"(anSdkConstantTypewithkind: "constant",value: "green",valueType.kind: "string"), losing the reference to theColorsenum entirely. Without@alternateType, the single-member enum correctly emits askind: "enum"withname: "Colors".The C# emitter then handles the constant case: In
type-converter.jsfromSdkType(), thecase "constant":branch:The fix should likely be in the
fromSdkTypefunction intype-converter.ts(case "constant":branch) to check if the original property type was an enum and preserve that enum type instead of collapsing to a constant.Alternatively, this could also be addressed in TCGC (
@azure-tools/typespec-client-generator-core) so it does not resolve@alternateType("green")on an enum-typed property as a plain string constant.Related issues