`anyof` keyword is not converted appropreately
Description
OpenAPI schema
"SchemaX": {
"anyOf" : [SchemaA, SchemaB]
}
is converted to
type SchemaX = Partial<SchemaA & SchemaB>
, but I think it shoud be converted to
type SchemaX = SchemaA | SchemaB
.
Maybe its source code is arround https://github.com/aspida/openapi2aspida/blob/main/src/builderUtils/props2String.ts#L37-L40 .
Environment
-
Package version:
v0.19.0 -
OS:
- [x] Linux
- [ ] Windows
- [ ] macOS
-
Node.js version:
v18.2.0 -
npm version:
8.9.0
Additional context
Thanks for developing this awesome library!
From the description on this site, it seems that the implementation of anyOf is incomplete but not wrong.
https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/
For the example of the page, schemas of PetByAge and PetByType are represented in Typescript as
type PetByAge = {
age: number
nickname?: string
}
type PetByType = {
pet_type: 'Cat' | 'Dog'
hunts?: boolean
}
, and considering two types below,
type SchemaX = Partial<PetByAge & PetByType>
type SchemaY = PetByAge | PetByType
I think a union type represents more precisely the schema as documented.
Because the schema of anyof PetByAge and PetByType should reject
{
"nickname": "Mr. Paws",
"hunts": false
}
, but SchemaX accepts it and SchemaY reject.
const x: SchemaX = {"nickname": "Mr. Paws", "hunts": false} // assignable :(
const y: SchemaY = {"nickname": "Mr. Paws", "hunts": false} // error, not assignable :)
And also Schema Y accepts all objects that the schema accepts
const y: SchemaY = { "age": 1 }
const y: SchemaY = { "pet_type": "Cat", "hunts": true }
const y: SchemaY = { "nickname": "Fido", "pet_type": "Dog", "age": 4}
And I found other wrong case.
Considering the case below,
components:
schemas:
schemaA:
type: object
properties:
id:
type: integer
required:
- id
schemaB:
type: object
properties:
id:
type: string
required:
- id
schemaX:
anyof:
- $ref: '#/components/schemas/schemaA'
- $ref: '#/components/schemas/schemaB'
schemaA and schemaB will be converted to
type SchemaA = { id: number }
type SchemaB = { id: string }
and schemaX should accept { id: string } or { id: number }.
However, schemaX is converted to
type SchemaX = Partial<schemaA & schemaB>
// = {id?: undefined}
with current implementation because schemaA & schemaB is { id: never }.
On the otherhand, if with union type implementation, SchemaX will be converted to
type SchemaX = SchemaA | SchemaB
// = {id: string | integer}
.
@solufa Is there any chance this feature request will be accepted?
If needed, I am able to create PR.
Fixed in v0.23.0