-
-
Notifications
You must be signed in to change notification settings - Fork 91
Open
Description
I think this is related to #513. If I have an object that is all of X and Y, and X is one of X1 or X2 and Y is one of Y1 or Y2, I'd expect that the resulting object would be (X1 | X2) & (Y1 | Y2) (or X & Y, since i don't have a preference how much decomposition there is), not (X1 | X2 | Y1 | Y2).
I'm not entirely sure how to fix this, but I have a test you can add to test/allof_oneof_test.ts that hits this issue and that continues the the player/team example of the other tests.
it("multiple 'allOf' and 'oneOf' nestings schema", async () => {
const base: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
allOf: [
{ $ref: '/test/multiple/allOf/oneOf/general' },
{ $ref: '/test/multiple/allOf/oneOf/team' },
{ $ref: '/test/multiple/allOf/oneOf/player' },
],
};
const general: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf/general',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
properties: {
id: { type: 'integer' },
type: { type: 'string' },
},
required: ['id', 'type'],
};
const team: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf/team',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
oneOf: [
{ $ref: '/test/multiple/allOf/oneOf/team1' },
{ $ref: '/test/multiple/allOf/oneOf/team2' },
],
};
const team1: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf/team1',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
properties: {
name: { type: 'string' },
},
required: ['id', 'name'],
};
const team2: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf/team2',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
properties: {
founded: { type: 'string' },
},
required: ['id', 'founded'],
};
const player: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf/player',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
oneOf: [
{ $ref: '/test/multiple/allOf/oneOf/player1' },
{ $ref: '/test/multiple/allOf/oneOf/player2' },
],
};
const player1: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf/player1',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
properties: {
firstName: { type: 'string' },
lastName: { type: 'string' },
},
required: ['id', 'firstName', 'lastName'],
};
const player2: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf/player2',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
properties: {
name: { type: 'string' },
born: { type: 'string' },
},
required: ['id', 'name', 'born'],
};
const result = await dtsGenerator({
contents: [
base,
general,
team,
player,
team1,
team2,
player1,
player2,
].map((s) => parseSchema(s)),
});
const expected = `declare namespace Test {
namespace Multiple {
namespace AllOf {
export type OneOf = {
id: number;
type: string;
} & (OneOf.Team1 | OneOf.Team2) & (OneOf.Player1 | OneOf.Player2);
namespace OneOf {
export interface General {
id: number;
type: string;
}
export type Player = Player1 | Player2;
export interface Player1 {
firstName: string;
lastName: string;
}
export interface Player2 {
name: string;
born: string;
}
export type Team = Team1 | Team2;
export interface Team1 {
name: string;
}
export interface Team2 {
founded: string;
}
}
}
}
}
`;
assert.strictEqual(result, expected);
});
or (to show that the issue persists even when X and Y parenthesize the oneOf correctly
it("multiple 'allOf' and 'oneOf' nestings schema", async () => {
const base: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
allOf: [
{ $ref: '/test/multiple/allOf/oneOf/team' },
{ $ref: '/test/multiple/allOf/oneOf/player' },
],
};
const general: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf/general',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
properties: {
id: { type: 'integer' },
type: { type: 'string' },
},
required: ['id', 'type'],
};
const team: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf/team',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
allOf: [
{ $ref: '/test/multiple/allOf/oneOf/general' },
{
oneOf: [
{ $ref: '/test/multiple/allOf/oneOf/team1' },
{ $ref: '/test/multiple/allOf/oneOf/team2' },
],
},
],
};
const team1: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf/team1',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
properties: {
name: { type: 'string' },
},
required: ['id', 'name'],
};
const team2: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf/team2',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
properties: {
founded: { type: 'string' },
},
required: ['id', 'founded'],
};
const player: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf/player',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
allOf: [
{ $ref: '/test/multiple/allOf/oneOf/general' },
{
oneOf: [
{ $ref: '/test/multiple/allOf/oneOf/player1' },
{ $ref: '/test/multiple/allOf/oneOf/player2' },
],
},
],
};
const player1: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf/player1',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
properties: {
firstName: { type: 'string' },
lastName: { type: 'string' },
},
required: ['id', 'firstName', 'lastName'],
};
const player2: JsonSchemaDraft07.Schema = {
$id: '/test/multiple/allOf/oneOf/player2',
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
properties: {
name: { type: 'string' },
born: { type: 'string' },
},
required: ['id', 'name', 'born'],
};
const result = await dtsGenerator({
contents: [
base,
general,
team,
player,
team1,
team2,
player1,
player2,
].map((s) => parseSchema(s)),
});
const expected = `declare namespace Test {
namespace Multiple {
namespace AllOf {
export type OneOf = {
id: number;
type: string;
} & (OneOf.Team1 | OneOf.Team2) & (OneOf.Player1 | OneOf.Player2);
namespace OneOf {
export interface General {
id: number;
type: string;
}
export type Player = {
id: number;
type: string;
} & (Player1 | Player2);
export interface Player1 {
firstName: string;
lastName: string;
}
export interface Player2 {
name: string;
born: string;
}
export type Team = {
id: number;
type: string;
} & (Team1 | Team2);
export interface Team1 {
name: string;
}
export interface Team2 {
founded: string;
}
}
}
}
}
`;
assert.strictEqual(result, expected);
});
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels