Skip to content

Commit

Permalink
fix: always expose referred DefinitionType to avoid issues with recur…
Browse files Browse the repository at this point in the history
…sive intersections of unions

Co-authored-by: Kari Lavikka <kari.lavikka@bdb.fi>
  • Loading branch information
domoritz and tuner committed Jan 14, 2022
1 parent bd6ab13 commit 7d108c6
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 4 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
},
"jest.autoRun": "off"
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
"test:coverage": "yarn jest test/ --collectCoverage=true",
"test:update": "cross-env UPDATE_SCHEMA=true yarn test:fast",
"debug": "node -r ts-node/register --inspect-brk ts-json-schema-generator.ts",
"run": "ts-node ts-json-schema-generator.ts",
"run": "ts-node-transpile-only ts-json-schema-generator.ts",
"release": "yarn build && auto shipit"
}
}
9 changes: 7 additions & 2 deletions src/TypeFormatter/ReferenceTypeFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@ export class ReferenceTypeFormatter implements SubTypeFormatter {
return { $ref: `#/definitions/${this.encodeRefs ? encodeURIComponent(ref) : ref}` };
}
public getChildren(type: ReferenceType): BaseType[] {
if (type.getType() instanceof DefinitionType) {
return [];
const referredType = type.getType();
if (referredType instanceof DefinitionType) {
// We probably already have the definitions for the children created so we could return `[]`.
// There are cases where we may not have (in particular intersections of unions with recursion).
// To make sure we create the necessary definitions, we return the children of the referred type here.
// Because we cache definitions, this should not incur any performance impact.
return this.childTypeFormatter.getChildren(referredType);
}

// this means that the referred interface is private
Expand Down
4 changes: 4 additions & 0 deletions test/valid-data-type.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ describe("valid-data-type", () => {
"type-intersection-recursive-interface",
assertValidSchema("type-intersection-recursive-interface", "Intersection")
);
it(
"type-intersection-union-recursive-interface",
assertValidSchema("type-intersection-union-recursive-interface", "Intersection")
);
it("type-intersection-union", assertValidSchema("type-intersection-union", "MyObject"));
it("type-intersection-union-enum", assertValidSchema("type-intersection-union-enum", "MyObject"));
it("type-intersection-union-primitive", assertValidSchema("type-intersection-union", "MyObject"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export interface Container {
child: Union;
}

export interface Dummy {
x: number;
}

export interface Silly {
y: number;
}

export type Union = Container | Silly;

export type Intersection = Union & Dummy;
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"$ref": "#/definitions/Intersection",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"Container": {
"additionalProperties": false,
"properties": {
"child": {
"$ref": "#/definitions/Union"
}
},
"required": [
"child"
],
"type": "object"
},
"Intersection": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"child": {
"$ref": "#/definitions/Union"
},
"x": {
"type": "number"
}
},
"required": [
"child",
"x"
],
"type": "object"
},
{
"additionalProperties": false,
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
}
},
"required": [
"x",
"y"
],
"type": "object"
}
]
},
"Silly": {
"additionalProperties": false,
"properties": {
"y": {
"type": "number"
}
},
"required": [
"y"
],
"type": "object"
},
"Union": {
"anyOf": [
{
"$ref": "#/definitions/Container"
},
{
"$ref": "#/definitions/Silly"
}
]
}
}
}

0 comments on commit 7d108c6

Please sign in to comment.