Skip to content

Fix: honor nullable: true on object types with additionalProperties#65

Open
david-velasquez-v wants to merge 2 commits into
rametta:mainfrom
david-velasquez-v:fix/nullable-dictionary-types
Open

Fix: honor nullable: true on object types with additionalProperties#65
david-velasquez-v wants to merge 2 commits into
rametta:mainfrom
david-velasquez-v:fix/nullable-dictionary-types

Conversation

@david-velasquez-v

@david-velasquez-v david-velasquez-v commented Jun 8, 2026

Copy link
Copy Markdown

Summary

src/common/util.ts handles nullable: true correctly for every type case except when additionalProperties is set on an object. There are two code paths that produce a dictionary type, and both forgot to wrap with appendNullToUnion:

  1. schemaObjectTypeNode short-circuits on item.additionalProperties before reaching the switch.
  2. nonArraySchemaObjectTypeToTs case "object" returns directly from the additionalProperties branch.

This PR adds the missing wrap at both sites.

Repro

Given the following OpenAPI 3.0 schema:

SomeNullableDictionary:
  type: object
  additionalProperties: true
  nullable: true

Before: type SomeNullableDictionary = { [key: string]: any }; (no | null)
After: type SomeNullableDictionary = { [key: string]: any } | null;

Same applies to additionalProperties: { type: "string" } with nullable: true, etc.

Test

Added a regression test in spec/common/types.spec.ts covering both shapes:

  • type: object, additionalProperties: true, nullable: true
  • type: object, additionalProperties: { type: "string" }, nullable: true
  • I have added or updated unit tests for this change.
  • I have updated the changelog with info about the changes in this PR

`nonArraySchemaObjectTypeToTs` wraps the non-dictionary return in its
`case "object"` branch via `appendNullToUnion(..., item.nullable)`, but
the dictionary return (`additionalProperties` is truthy) did not. The
same pattern exists in `schemaObjectTypeNode`, which short-circuits to
`createDictionaryType` before reaching the switch and also dropped
`item.nullable`. Every other type branch handles `item.nullable`;
these two dictionary paths were the only exceptions.

Result: schemas like

    type: object
    additionalProperties: true
    nullable: true

generated `{ [key: string]: any }` instead of
`{ [key: string]: any } | null`, silently dropping the null case.

Added regression coverage for both shapes:
- `additionalProperties: true` + `nullable: true`
- `additionalProperties: { type: "string" }` + `nullable: true`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant