Skip to content

[Bug]: parameters preset deserializer emits non-compiling code (date-time not converted + enum cast to inline union) #461

Description

@ALagoni97

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions