Skip to content

responses.case: "preserve" and requests.case: "preserve" do not preserve acronym casing for operation-derived types #3797

@thomasvanlankveld

Description

@thomasvanlankveld

Description

Description

When a schema definition uses an acronym in its name (e.g. HTTPRequest), definitions.case: "preserve" correctly preserves the acronym in the emitted type.

When an operation's operationId contains the same acronym (e.g. RequestOperations_describeHTTPRequest), the derived *Data / *Response / *Responses type aliases emit the acronym with only the first letter uppercase (Http), despite requests.case: "preserve", responses.case: "preserve", and errors.case: "preserve" being set.

My reading is that these three nested settings are supposed to preserve the original casing coming from the operationId, analogous to how definitions.case: "preserve" preserves schema names. In practice they only preserve the overall PascalCase/camelCase shape, not the acronym casing inside the identifier.

This also affects the SDK plugin's generated method name (requestOperationsDescribeHttpRequest), presumably because the method-name derivation runs through the same internal normalization step before case is applied.

Related: the resolution in #3596 suggested nesting case: "preserve" under definitions / responses etc. That resolves the schema-definition case but not the operation-derived case, so the two situations may have been conflated. Also related: #2814, which describes the same category of problem for Responses / Data / Error types.

Why this matters

Our OpenAPI spec uses acronyms throughout (both as schema names and inside operationIds). A working case: "preserve" for operation-derived types would let us delete a fragile post-codegen text-replacement step we currently maintain to restore acronym casing.

Reproducible example or configuration

Example: https://stackblitz.com/edit/hey-api-client-fetch-example-ghmf7pyz?file=src%2Fclient%2Ftypes.gen.ts

Files included in this repro:

  • openapi.yaml — minimal spec with one schema (HTTPRequest) and one operation (RequestOperations_describeHTTPRequest)
  • openapi-ts.config.ts@hey-api/typescript with nested case: "preserve" on definitions, requests, responses, and errors
  • package.json@hey-api/openapi-ts@^0.96.0

Steps: npm install && npx openapi-ts

Expected output

export type HTTPRequest = { ... }                              // preserved (OK)
export type requestOperationsDescribeHTTPRequestData = ...     // HTTP preserved
export type requestOperationsDescribeHTTPRequestResponses = ...// HTTP preserved
export type requestOperationsDescribeHTTPRequestResponse = ... // HTTP preserved

Actual output

export type HTTPRequest = { ... }                              // preserved (OK)
export type requestOperationsDescribeHttpRequestData = ...     // "Http" instead of "HTTP"
export type requestOperationsDescribeHttpRequestResponses = ...
export type requestOperationsDescribeHttpRequestResponse = ...

OpenAPI specification (optional)

openapi: 3.1.0
info:
  title: Acronym Casing Repro
  version: 1.0.0
paths:
  /requests/{id}:
    get:
      operationId: RequestOperations_describeHTTPRequest
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HTTPRequest"
components:
  schemas:
    HTTPRequest:
      type: object
      properties:
        id:
          type: string
      required:
        - id

System information (optional)

  • @hey-api/openapi-ts 0.96.0
  • Node.js 24.15.0
  • npm 11.12.1
  • macOS (Darwin 25.3.0 arm64)

Metadata

Metadata

Labels

bug 🔥Broken or incorrect behavior.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions