TypeScript: primitive-collection union members serialized as objects (composed-type if/default clause collection classification)
- Dominant language
- C#
- Stars
- 3.8k
- Forks
- 333
- Avg merge
- 16h 29m
- Merged PRs (30d)
- 116
Description
### What are you generating using Kiota, clients or plugins?
API Client/SDK
### In what context or format are you using Kiota?
Source Build
### Client library/SDK language
TypeScript
### Describe the bug
Split out from PR #7995 review feedback (Copilot review comment on `src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs`).
In `WriteComposedTypeIfClause` (~line 574) and `WriteComposedTypeDefaultClause` (~line 605), the primitive-branch filter uses `IsPrimitiveType(x, composedType)` with collection information included. For union members that are **primitive collections** (e.g. `string[]`, `ArrayBuffer[]`), the type string becomes `string[]`/`ArrayBuffer[]`, which is not in the primitive switch, so `IsPrimitiveType` returns `false`. As a result these members fall through to the default clause and are serialized via `writeCollectionOfObjectValues` instead of a primitive-collection writer.
Two related observations:
- The classification here is inconsistent with the function serializer/deserializer paths (`WriteComposedTypeSerializer`, `WriteComposedTypeDeserializer`), which already use the collection-insensitive `IsPrimitiveType(x, composedType, false)`.
- Because collections are filtered out before `GetPrimitiveTypeCheck` is reached, the `type.IsCollection` branch that was added in #7995 (the `Array.isArray(...).every(...)` guard) is currently unreachable.
### Expected behavior
A union member that is a primitive collection (e.g. `string[]`, `ArrayBuffer[]`) should be serialized/deserialized as a primitive collection (e.g. `writeCollectionOfPrimitiveValues` / byte-array handling), not via object serialization.
### How to reproduce
Generate a TypeScript client from a schema containing a property whose type is a union of primitive collections (e.g. `oneOf: [ {type: array, items: {type: string}}, {type: array, items: {type: number}} ]`) and inspect the generated serializer/deserializer for that property.
### Open API description file
N/A (synthetic union-of-primitive-collections schema)
### Kiota Version
1.34.1 (source build)
### Known Workarounds
None needed for the common scalar binary-union case (`binary | base64`), which is handled correctly. This only affects union members that are themselves primitive collections.
### Other information
Deferred from #7995 because it is a pre-existing latent edge case unrelated to that PR's scalar binary-union fix, and a correct fix must also adjust the `as {nodeType}` cast (which currently uses the element type without `[]`) and add dedicated primitive-collection-union regression tests. Fixing it under the approved PR would broaden scope and risk regressions.
Contributor guide
Research direction
Start in src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs at WriteComposedTypeIfClause and WriteComposedTypeDefaultClause, then compare their classification with WriteComposedTypeSerializer and WriteComposedTypeDeserializer. Add dedicated regression tests for unions of primitive collections; done means generated code uses primitive-collection or byte-array handling rather than object serialization and preserves the collection type in the cast.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100