orval-labs / orval

orval is able to generate client with appropriate type-signatures (TypeScript) from any valid OpenAPI v3 or Swagger v2 specification, either in yaml or json formats. 🍺
https://orval.dev
MIT License
3.16k stars 335 forks source link

Required properties across `allOf`s don't work #1670

Open Edward-Upton opened 3 weeks ago

Edward-Upton commented 3 weeks ago

What are the steps to reproduce this issue?

  1. Generate an OpenAPI schema that has a component with optional properties, then try and set those properties as required in other item in an allOf, e.g:
    components:
    schemas:
    ContractPartial:
      type: object
      properties:
        uuid:
          type: string
        description:
          type: string
        start_date:
          type: string
          format: date
        end_date:
          type: string
          format: date
    Contract:
      type: object
      allOf:
        - $ref: '#/components/schemas/ContractPartial'
        - type: object
          properties:
            active:
              type: boolean
              description: If this contract is current active.
          required:
            - description
            - end_date
            - start_date
            - uuid
  2. Generate the Orval code, and these types will be like the following:
    
    export type ContractPartial = {
    uuid?: string;
    description?: string;
    start_date?: string;
    end_date?: string;
    }

export type ContractAllOf = { active: boolean; };

export type Contract = ContractPartial & ContractAllOf;


## What happens?

Notice that the outputted generated types do not specify that uuid, description, start_date and end_date should be required.

## What were you expecting to happen?

Like other OpenAPI generators (e.g. [oapi-codegen](https://github.com/oapi-codegen/oapi-codegen) generate these types as required). In this case, it potentially would look something like:

```ts
type RequiredKeys<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;

export type ContractPartial = {
  uuid?: string;
  description?: string;
  start_date?: string;
  end_date?: string;
}

export type ContractAllOf = {
  active: boolean;
};

export type Contract = RequiredKeys<ContractPartial & ContractAllOf, "uuid" | "description" | "start_date" | "end_date" | "area">;

## What versions are you using?

System: OS: Linux 4.18 Rocky Linux 8.8 (Green Obsidian) CPU: (4) x64 Intel(R) Xeon(R) Gold 6132 CPU @ 2.60GHz Memory: 2.16 GB / 11.45 GB Container: Yes Shell: 3.6.1 - /usr/bin/fish npmPackages: axios: ^1.3.6 => 1.3.6 msw: ^2.2.0 => 2.2.0 orval: ^7.2.0 => 7.2.0

jorge-ui commented 1 day ago

Yes, I'm also having this issue. Using allOfs to define a type in a OAS spec file produces a union type when generating TypeScript:

type MyUnionType = SomeType & SomeOtherType;

This is great, but the issue is that the generated types are not completely inheriting the properties marked as required despite being defined in the specs, and are instead being generated as optional, this means extra care from the dev to verify the type's usage and handle them to satisfy the ts compiler, minor inconvenience and somewhat annoying, though not a dealbreaker.