Skip to content

[BUG][typescript-axios] Missing import for a $ref under additionalProperties on a 3.1 nullable property #24517

Description

@rony-remedio

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • What's the version of OpenAPI Generator used?
  • Have you search for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Bounty to sponsor the fix
Description

When a property is nullable using an OpenAPI 3.1 type array ("type": ["null", "object"]) and its additionalProperties is a $ref, the generated model references the $ref'd type but never imports it, so the output does not compile.

Instead of importing the referenced model, the generator emits an import for a Null model that it never writes:

// @ts-ignore
import type { Null } from './null';        // <- ./null is never generated
export interface ParentNullableMap {
    'map'?: { [key: string]: Child; };     // <- Child referenced, never imported
}

tsc then fails with:

models/parent-nullable-map.ts(21,30): error TS2304: Cannot find name 'Child'.

Two things narrow it down:

  1. The nullable type array is what triggers it. With "type": "object" instead of "type": ["null", "object"], the same property imports Child correctly.
  2. additionalProperties is specific. A nullable array of the same $ref ("type": ["null", "array"] with items: {$ref}) is generated correctly, in the same run — included below as a control.

The nullable is also silently dropped on the affected property: 'map'?: { [key: string]: Child; } has no | null, while the control correctly produces 'list'?: Array<Child> | null.

Reproduces with withSeparateModelsAndApi=true.

openapi-generator version

7.24.0 (via the openapitools/openapi-generator-cli:v7.24.0 Docker image). Not tested against earlier versions.

OpenAPI declaration file content or url
{
  "openapi": "3.1.0",
  "info": {"title": "repro", "version": "1.0.0"},
  "paths": {},
  "components": {
    "schemas": {
      "Child": {"type": "object", "properties": {"name": {"type": "string"}}},
      "ParentNullableMap": {
        "type": "object",
        "properties": {
          "map": {"type": ["null", "object"], "additionalProperties": {"$ref": "#/components/schemas/Child"}}
        }
      },
      "ParentNullableArray": {
        "type": "object",
        "properties": {
          "list": {"type": ["null", "array"], "items": {"$ref": "#/components/schemas/Child"}}
        }
      }
    }
  }
}

validate reports no errors on this spec (only "unused model" recommendations, since paths is empty).

Command line used for generation
docker run --rm -v "$PWD:/local" openapitools/openapi-generator-cli:v7.24.0 \
  generate -i /local/minimal.json -g typescript-axios -o /local/out \
  --additional-properties=withSeparateModelsAndApi=true,modelPackage=models,apiPackage=api
Steps to reproduce
  1. Save the spec above as minimal.json.
  2. Run the command above.
  3. models/parent-nullable-map.ts imports Null from ./null and references Child with no import for it. models/null.ts does not exist.
  4. models/parent-nullable-array.ts — the control — imports Child correctly.
  5. Type-check the output, e.g. tsc --noEmit --strict --skipLibCheck --target es2020 --module esnext --moduleResolution bundler models/*.ts, and it fails with TS2304: Cannot find name 'Child'.
Actual output
// models/parent-nullable-map.ts  (BROKEN)
// @ts-ignore
import type { Null } from './null';
export interface ParentNullableMap {
    'map'?: { [key: string]: Child; };
}

// models/parent-nullable-array.ts  (control, correct)
// @ts-ignore
import type { Child } from './child';
export interface ParentNullableArray {
    'list'?: Array<Child> | null;
}
Expected output
// models/parent-nullable-map.ts
import type { Child } from './child';
export interface ParentNullableMap {
    'map'?: { [key: string]: Child; } | null;
}
Related issues/PRs
Suggest a fix

The nullable type array appears to be consumed before the $ref inside additionalProperties is registered as an import, and a Null model is substituted in its place. Two observations that may help locate it:

  • The Null import is emitted for the nullable-type-array case generally, not only when a bare {"type": "null"} schema exists — the spec above contains no such schema, yet the import appears.
  • The // @ts-ignore above generated imports masks the dangling ./null import, so the failure surfaces at the usage site rather than the import, which makes it harder to trace. In the array (control) path the same @ts-ignore line is present but the import is correct.

A workaround for anyone hitting this: pre-process the spec to drop "null" from the type array on properties whose additionalProperties is a $ref (accepting the loss of nullability on those properties), which restores a compiling client.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions