metadevpro / openapi3-ts

TS Model & utils for creating and exposing OpenAPI 3.x contracts.
MIT License
485 stars 64 forks source link

When using oneOf with objects that have different properties, typescript assumes the list type and breaks #58

Closed zardilior closed 4 years ago

zardilior commented 4 years ago

This is a valid json schema which breaks with the implementation used in this library

oneOf: [
   {
        type: 'object',
        required: ['status'],
        properties: {
          status: { type: 'string', pattern: JobApplicant.Status.NEW },
          payload: {
            type: 'string'
          },
        }
      }, {
        type: 'object',
        required: ['status'],
        properties: {
          status: { type: 'string', pattern: 'contact' },
        }
      }
]

Breaks with error Type '{ status: { type: string; pattern: string; }; payload?: undefined; }' is not assignable to type '{ [propertyName: string]: ReferenceObject | SchemaObject; }'. as the second option hasn't such type payload

pjmolina commented 4 years ago

Interesting case. Looks like the TS compiler is inferring the type of the list based on the first item of the list. Did you tried to cast with as any to by pass TS inference checking?

zardilior commented 4 years ago

@pjmolina I haven't but this error also happens if you switch the objects places

zardilior commented 4 years ago

It works this way:

oneOf: [
   {
        type: 'object',
        required: ['status'],
        properties: {
          status: { type: 'string', pattern: JobApplicant.Status.NEW },
          payload: {
            type: 'string'
          },
        }
      } as any, {
        type: 'object',
        required: ['status'],
        properties: {
          status: { type: 'string', pattern: 'contact' },
        }
      }
]
pjmolina commented 4 years ago

As commented, looks like the case is related to the type inference on the TypeScript compiler. Nothing can be done o this library to that respect. Forced casts as suggested can help to give hints to the TS compiler. Thus, closing. Feel free to reopen if we can improve it in any way.