Description
The parameters preset generates a URL deserializer that assigns raw string values to typed properties without conversion. Two independent defects, both producing tsc failures. Generation reports zero errors.
Sibling to #372, which covers two defects in the same preset on the serialization side (query-param casing, missing deserializeUrl). These two are on the deserialization side and are not fixed by it.
On a real 88-operation OpenAPI document this accounted for 22 of 28 total type errors across 8 parameter files, so it is likely to affect most non-trivial specs.
1. date-time query parameters are never converted
A parameter with format: date-time generates a Date-typed property, but the deserializer assigns the decoded string straight to it.
// generated
if (params.has('from_time')) {
const value = params.get('from_time');
if (value) {
const decodedValue = decodeURIComponent(value);
this.fromTime = decodedValue; // string -> Date
}
}
TS2322: Type 'string' is not assignable to type 'Date'.
15 occurrences in the sample document.
2. Enum parameters are cast to an inline union instead of the declared named type
The property is declared with the named enum type, but the deserializer casts to a structurally-identical inline union. TypeScript treats the two as distinct, so the assignment fails.
// property is declared as: CarrierCode | undefined
this.carrierCode = decodedValue as 'airmee' | 'alpi' | 'asendia' | 'bring' | 'ups'; /* …65 more… */
TS2322: Type '"bring" | "pdk" | "ups" | ...' is not assignable to type 'CarrierCode'.
7 occurrences, including LabelsGetParameters (LabelFormat).
Reproduction
{
"openapi": "3.0.1",
"info": { "title": "Param deserialize repro", "version": "1.0.0" },
"paths": {
"/items": {
"get": {
"operationId": "itemsGet",
"parameters": [
{
"name": "from_time",
"in": "query",
"schema": { "type": "string", "format": "date-time" }
},
{
"name": "carrier_code",
"in": "query",
"schema": { "$ref": "#/components/schemas/CarrierCode" }
}
],
"responses": { "200": { "description": "OK" } }
}
}
},
"components": {
"schemas": {
"CarrierCode": { "type": "string", "enum": ["gls", "dao", "ups"] }
}
}
}
codegen generate && tsc --noEmit
Expected
this.fromTime = new Date(decodedValue);
this.carrierCode = decodedValue as CarrierCode;
For (1), the round-trip matters as much as the compile: serializeQueryParameters() needs to emit the matching wire format (presumably .toISOString()) so deserialize(serialize(x)) returns an equal value. Worth a runtime test rather than only a snapshot, since a snapshot will happily lock in a broken round-trip.
For (2), the fix is to reference the named type that was already generated rather than re-rendering the union inline. If a named model exists for the enum, the cast should use it.
Notes
Both defects are in the deserialization path only — the serializers in the same generated files use the correct property types. That asymmetry suggests the deserializer branch renders types from the raw schema while the property declarations render from the processed model, and the two disagree.
Since #372, #373 and this issue are all "preset emits non-compiling code" found the same way, a blackbox case that type-checks generated output for a spec exercising date-time params, named enum params, and nullable arrays together would likely catch the next one before release.
Environment
- CLI version: 0.82.1 (built from source, matches published
latest)
- Node: 22
- OS: Windows 11
- Input: OpenAPI 3.0.1, 72 paths / 88 operations, 76 generated parameter models
Description
The
parameterspreset generates a URL deserializer that assigns rawstringvalues to typed properties without conversion. Two independent defects, both producingtscfailures. Generation reports zero errors.Sibling to #372, which covers two defects in the same preset on the serialization side (query-param casing, missing
deserializeUrl). These two are on the deserialization side and are not fixed by it.On a real 88-operation OpenAPI document this accounted for 22 of 28 total type errors across 8 parameter files, so it is likely to affect most non-trivial specs.
1.
date-timequery parameters are never convertedA parameter with
format: date-timegenerates aDate-typed property, but the deserializer assigns the decoded string straight to it.15 occurrences in the sample document.
2. Enum parameters are cast to an inline union instead of the declared named type
The property is declared with the named enum type, but the deserializer casts to a structurally-identical inline union. TypeScript treats the two as distinct, so the assignment fails.
7 occurrences, including
LabelsGetParameters(LabelFormat).Reproduction
{ "openapi": "3.0.1", "info": { "title": "Param deserialize repro", "version": "1.0.0" }, "paths": { "/items": { "get": { "operationId": "itemsGet", "parameters": [ { "name": "from_time", "in": "query", "schema": { "type": "string", "format": "date-time" } }, { "name": "carrier_code", "in": "query", "schema": { "$ref": "#/components/schemas/CarrierCode" } } ], "responses": { "200": { "description": "OK" } } } } }, "components": { "schemas": { "CarrierCode": { "type": "string", "enum": ["gls", "dao", "ups"] } } } }codegen generate && tsc --noEmitExpected
For (1), the round-trip matters as much as the compile:
serializeQueryParameters()needs to emit the matching wire format (presumably.toISOString()) sodeserialize(serialize(x))returns an equal value. Worth a runtime test rather than only a snapshot, since a snapshot will happily lock in a broken round-trip.For (2), the fix is to reference the named type that was already generated rather than re-rendering the union inline. If a named model exists for the enum, the cast should use it.
Notes
Both defects are in the deserialization path only — the serializers in the same generated files use the correct property types. That asymmetry suggests the deserializer branch renders types from the raw schema while the property declarations render from the processed model, and the two disagree.
Since #372, #373 and this issue are all "preset emits non-compiling code" found the same way, a blackbox case that type-checks generated output for a spec exercising date-time params, named enum params, and nullable arrays together would likely catch the next one before release.
Environment
latest)