openapi-ts / openapi-typescript

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

bug: request body fields with default values are treated as required #1741

Closed ysemennikov closed 5 days ago

ysemennikov commented 2 weeks ago

Description

We have generated TS interfaces using our OpenAPI 3.1.0 specification. There are some parameters that have default values (so they are not required in request, and the body without them will be still valid):

image

However, these parameters are treated as required when generating paths:

image
Name Version
openapi-typescript 7.0.1
Node.js 20.13.1
OS + version macOS Sonoma 14.4

Reproduction

Try to use this openapi schema:

"src__schemas__social_profiles__Create": {
  "properties": {
    "card_title": {
      "type": "string",
      "maxLength": 64,
      "minLength": 1,
      "title": "Card Title",
      "default": "Social Profile"
    },
    "template": {
      "type": "string",
      "maxLength": 64,
      "minLength": 1,
      "title": "Template"
    },
    "photo": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 2083,
          "minLength": 1,
          "format": "uri"
        },
        {
          "const": ""
        }
      ],
      "title": "Photo",
      "default": ""
    },
    "signature": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 2083,
          "minLength": 1,
          "format": "uri"
        },
        {
          "const": ""
        }
      ],
      "title": "Signature",
      "default": ""
    },
    "design": {
      "type": "object",
      "title": "Design",
      "default": {

      }
    },
    "details": {
      "type": "object",
      "title": "Details",
      "default": {

      }
    },
    "socials": {
      "type": "object",
      "title": "Socials",
      "default": {

      }
    },
    "meta": {
      "type": "object",
      "title": "Meta",
      "default": {

      }
    }
  },
  "type": "object",
  "required": [
    "template"
  ],
  "title": "Create",
  "description": "Social Profile schema for create."
}

You can see that default values are set, but the fields are not recognized as not required.

Expected result

Parameters that have default values have | undefined in type declaration, like

type SocialProfileCreate = {
    card_title: string;
    template: string;
    photo?: string | "";
    signature?: string | "";
    design?: Record<string, never>;
    details?: Record<string, never>;
    socials?: Record<string, never>;
    meta?: Record<string, never>;
}

Checklist

phk422 commented 2 weeks ago

Description

We have generated TS interfaces using our OpenAPI 3.1.0 specification. There are some parameters that have default values (so they are not required in request, and the body without them will be still valid):

image

However, these parameters are treated as required when generating paths:

image

Name Version openapi-typescript 7.0.1 Node.js 20.13.1 OS + version macOS Sonoma 14.4 Reproduction

Try to use this openapi schema:

"src__schemas__social_profiles__Create": {
  "properties": {
    "card_title": {
      "type": "string",
      "maxLength": 64,
      "minLength": 1,
      "title": "Card Title",
      "default": "Social Profile"
    },
    "template": {
      "type": "string",
      "maxLength": 64,
      "minLength": 1,
      "title": "Template"
    },
    "photo": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 2083,
          "minLength": 1,
          "format": "uri"
        },
        {
          "const": ""
        }
      ],
      "title": "Photo",
      "default": ""
    },
    "signature": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 2083,
          "minLength": 1,
          "format": "uri"
        },
        {
          "const": ""
        }
      ],
      "title": "Signature",
      "default": ""
    },
    "design": {
      "type": "object",
      "title": "Design",
      "default": {

      }
    },
    "details": {
      "type": "object",
      "title": "Details",
      "default": {

      }
    },
    "socials": {
      "type": "object",
      "title": "Socials",
      "default": {

      }
    },
    "meta": {
      "type": "object",
      "title": "Meta",
      "default": {

      }
    }
  },
  "type": "object",
  "required": [
    "template"
  ],
  "title": "Create",
  "description": "Social Profile schema for create."
}

You can see that default values are set, but the fields are not recognized as not required.

Expected result

Parameters that have default values have | undefined in type declaration, like

type SocialProfileCreate = {
    card_title: string;
    template: string;
    photo?: string | "";
    signature?: string | "";
    design?: Record<string, never>;
    details?: Record<string, never>;
    socials?: Record<string, never>;
    meta?: Record<string, never>;
}

Checklist

Hi, @ysemennikov ! The results I generated using your scheme test were correct. image

duncanbeevers commented 2 weeks ago

@phk422 We're seeing this issue as well. Could the difference be that the requestBody is using a referenced component schema rather than an inline schema?

ysemennikov commented 2 weeks ago

@phk422 We're seeing this issue as well. Could the difference be that the requestBody is using a referenced component schema rather than an inline schema?

Hi @phk422, the requestBody in our OpenAPI schema was also referenced, not inline. Maybe this really makes sense?

phk422 commented 2 weeks ago

@phk422 We're seeing this issue as well. Could the difference be that the requestBody is using a referenced component schema rather than an inline schema?

Hi @phk422, the requestBody in our OpenAPI schema was also referenced, not inline. Maybe this really makes sense?

Ah, yes, I overlooked it. I already submitted a pr to fix it!