Azure / Azure/typespec-azure

[Bug]: Preserve property-level `@alternateType` for multipart `HttpPart` properties

Open
#5,292 1 comment 0 reactions 1 assignee Claimed by @iscai-msft View on GitHub
bug lib:tcgc triaged:core
Dominant language
TypeScript
Stars
27
Forks
90
Avg merge
1d 22h
Merged PRs (30d)
156

Description

### Describe the bug

The C# generator produces `double` instead of `float` when a multipart model property declared as `HttpPart` is decorated with a property-level `@alternateType(float32, "csharp")`. The same problem occurs with `@alternateType(HttpPart, "csharp")`.

The C# conversion layer and .NET generator appear to map the received SDK types correctly (`Float32` to `float` and `Numeric` to `double`). The issue is that the property-level alternate type is lost during TCGC multipart model construction.

In the upstream `addMultipartPropertiesToModelType` path, the property is initially created through `getSdkModelPropertyType(part.property)`, which honors the alternate type. The implementation then obtains the unwrapped payload via `getHttpBodyType(part.body)` and replaces `clientProperty.type` with `getClientTypeWithDiagnostics(bodyType)`, discarding the type selected from the decorated property.

### Reproduction

```typespec
model Form {
@alternateType(float32, "csharp")
value: HttpPart;
}

@post op upload(
@header contentType: "multipart/form-data",
@multipartBody body: Form,
): void;
```

Expected generated C# property type: `float`.

Actual generated C# property type: `double`.

Also reproduces with:

```typespec
@alternateType(HttpPart, "csharp")
```

Relevant investigation:
- The C# emitter delegates SDK-type construction through `createSdkContext`; the C# conversion layer consumes the already-overwritten SDK property type.
- The .NET generator maps `Float32` to `float` and `Numeric` to `double`, indicating that the incorrect type reaches the generator before C# mapping.
- Existing multipart tests cover payload conversion such as `HttpPart` and `HttpPart`, but do not cover property-level alternates.
- Existing C# alternate-type tests cover normal properties, but not multipart `HttpPart` properties.
- Related issue: https://github.com/microsoft/typespec/issues/8820

The likely fix is in the TCGC multipart-model construction path, specifically `addMultipartPropertiesToModelType` in `packages/typespec-client-generator-core/src/types.ts`: preserve a regular alternate type attached to `part.property` when replacing the synthetic `HttpPart` wrapper with its payload type, while retaining existing diagnostics for unsupported external-property alternates.

Suggested regression coverage:
1. `HttpPart` with `@alternateType(float32, "csharp")` produces SDK type `float32`.
2. The C# emitter model conversion yields a `Float32` input primitive.
3. Generated C# contains a `float` property.
4. Array parts preserve the alternate element type.
5. Undecorated multipart behavior remains `numeric`/`double`.

### Checklist

- [x] Follow our [Code of Conduct](https://github.com/azure/typespec-azure/blob/main/CODE_OF_CONDUCT.md)
- [x] Check that this issue is about the Azure libraries for typespec. For bug in the typespec language or core libraries file it in the [TypeSpec repo](https://github.com/Microsoft/TypeSpec/issues/new/choose)
- [x] Check that there isn't already an issue that request the same bug to avoid creating a duplicate.
- [x] The provided reproduction is a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) of the bug.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.