openapi-ts / openapi-typescript

Generate TypeScript types from OpenAPI 3 specs
https://openapi-ts.dev
MIT License
5.51k stars 451 forks source link

[openapi-typescript] Incorrect type generated for nullable objects #1821

Open JohanAlteruna opened 1 month ago

JohanAlteruna commented 1 month ago

Thanks everyone for the new updates of openapi-typescript! I have found an issue which I believe might be related to the new major version (7).

Description

In version 7.3.0 and OpenAPI version 3.0.3, combining type: object and nullable: true does not produce the expected union type.

Reproduction

Run the CLI with default options on the following schema:

openapi: "3.0.3"
info: { title: "Test", version: "0" }
servers:
  - url: "example.com"
components:
  schemas:
    obj1:
      type: object
      nullable: true
paths: {}

Expected result

schemas: {
  obj1: Record<string, never> | null;
};

Actual Result

schemas: {
  obj1: Record<string, never>;
};

Checklist

The example given above works fine with type: string and nullable: true. It also works in openapi-typescript version 6.7.6.

JohanAlteruna commented 1 month ago

As a side note, I also think that Record<string, never> should be replaced with a more inclusive type for arbitrary objects. For example, there are use cases in which API consumers and/or implementations are allowed to send objects with arbitrary properties (and arbitrary properties are allowed by default in JSON schema AFAIK). In such cases, Record<string, never> will prevent all legal values except for the empty object ({}). I would suggest that the type Record<string, unknown> is used instead.

drwpow commented 1 month ago

You’re right I don’t think we’re testing for this. This should be an easy fix and we’d welcome a PR on it from anyone 🙂

As a side note, I also think that Record<string, never> should be replaced with a more inclusive type for arbitrary objects.

We’ve had this suggestion before. But this library’s whole purpose is to help you catch where your runtime code deviates from your declared schema. As documented, if you declare an empty object in your schema, TS is going to flag this for you as a potential bug. Perhaps you’re autogenerating these schemas and there was a bug! It’s being overly strict for your benefit, to alert you of where your schema is incomplete, which is also at the boundary of where TS can’t typecheck for you anymore. Appreciate the suggestion, and we’ll always look for newer and better ways to do things. But in situations like this, we’ll always err on the side of being too strict rather than too loose.