From 57f0ac972d2178577f50155f56a73e71cd081458 Mon Sep 17 00:00:00 2001 From: york yao Date: Thu, 3 May 2018 08:28:57 +0800 Subject: [PATCH] fix: can inherit additional properties from heritage clauses --- demo/cases.json | 6 +++--- demo/cases.ts | 4 +++- demo/debug.json | 5 +++-- online/variables.ts | 4 +++- src/parser.ts | 21 ++++++++++++++------- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/demo/cases.json b/demo/cases.json index 7a8f69b..96f193c 100644 --- a/demo/cases.json +++ b/demo/cases.json @@ -108,7 +108,7 @@ "defaultType", "anyType" ], - "additionalProperties": false + "additionalProperties": true }, "NumberType": { "type": "object", @@ -392,7 +392,7 @@ } }, "required": [], - "additionalProperties": true, + "additionalProperties": {}, "minProperties": 1, "maxProperties": 1 }, @@ -572,7 +572,7 @@ "interfaceExtendsMember1", "interfaceExtendsMember2" ], - "additionalProperties": false + "additionalProperties": {} }, "TypeIntersection": { "type": "object", diff --git a/demo/cases.ts b/demo/cases.ts index fbd4c6e..083aae9 100644 --- a/demo/cases.ts +++ b/demo/cases.ts @@ -6,11 +6,12 @@ type TypeLiteral = { /** * @minProperties 1 * @maxProperties 1 - * @additionalProperties */ interface Interface { interfaceMember1?: number interfaceMember2?: string + + [name: string]: any } type TypeUnion1 = TypeLiteral | { @@ -285,6 +286,7 @@ type ReferenceType = { /** * @entry cases.json + * @additionalProperties */ export type EntryType = { optionalMember?: string; diff --git a/demo/debug.json b/demo/debug.json index 79e2f74..2556bd1 100644 --- a/demo/debug.json +++ b/demo/debug.json @@ -87,7 +87,7 @@ ], "minProperties": 1, "maxProperties": 1, - "additionalProperties": true + "additionalProperties": {} }, { "kind": "object", @@ -361,7 +361,7 @@ } ], "minProperties": 2, - "maxProperties": 4 + "additionalProperties": {} }, { "kind": "object", @@ -1322,6 +1322,7 @@ ], "minProperties": 20, "maxProperties": 22, + "additionalProperties": true, "entry": "cases.json" } ] \ No newline at end of file diff --git a/online/variables.ts b/online/variables.ts index 82f3fb5..79883db 100644 --- a/online/variables.ts +++ b/online/variables.ts @@ -13,11 +13,12 @@ export const demoCasesTs = `type TypeLiteral = { /** * @minProperties 1 * @maxProperties 1 - * @additionalProperties */ interface Interface { interfaceMember1?: number interfaceMember2?: string + + [name: string]: any } type TypeUnion1 = TypeLiteral | { @@ -292,6 +293,7 @@ type ReferenceType = { /** * @entry cases.json + * @additionalProperties */ export type EntryType = { optionalMember?: string; diff --git a/src/parser.ts b/src/parser.ts index 5064933..aad9787 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -108,9 +108,13 @@ export class Parser { return } - let { members, minProperties, maxProperties, additionalProperties } = this.getObjectMembers(declaration.members); + let { members, minProperties, maxProperties, additionalProperties } = this.getObjectMembers(declaration.members) - ({ minProperties, maxProperties } = this.handleHeritageClauses(declaration, members, minProperties, maxProperties)) + let additionalPropertiesFromHeritageClauses: Type | undefined | boolean + ({ minProperties, maxProperties, additionalProperties: additionalPropertiesFromHeritageClauses } = this.handleHeritageClauses(declaration, members, minProperties, maxProperties)) + if (additionalPropertiesFromHeritageClauses) { + additionalProperties = additionalPropertiesFromHeritageClauses + } const model: Model = { kind: 'object', @@ -130,25 +134,28 @@ export class Parser { } private handleHeritageClauses(declaration: ts.InterfaceDeclaration, members: Member[], minProperties: number, maxProperties: number) { + let additionalProperties: Type | undefined | boolean if (declaration.heritageClauses) { for (const clause of declaration.heritageClauses) { if (clause.kind === ts.SyntaxKind.HeritageClause) { for (const type of clause.types) { if (type.kind === ts.SyntaxKind.ExpressionWithTypeArguments) { - ({ minProperties, maxProperties } = this.handleExpressionWithTypeArguments(type.expression as ts.Identifier, members, minProperties, maxProperties)) + ({ minProperties, maxProperties, additionalProperties } = this.handleExpressionWithTypeArguments(type.expression as ts.Identifier, members, minProperties, maxProperties)) } } } } } - return { minProperties, maxProperties } + return { minProperties, maxProperties, additionalProperties } } private handleExpressionWithTypeArguments(declaration: ts.Identifier, members: Member[], minProperties: number, maxProperties: number) { const interfaceName = declaration.text this.preHandleType(interfaceName) + let additionalProperties: Type | undefined | boolean const clauseModel = this.models.find(m => m.kind === 'object' && m.name === interfaceName) if (clauseModel && clauseModel.kind === 'object') { + additionalProperties = clauseModel.additionalProperties for (const member of clauseModel.members) { if (members.every(m => m.name !== member.name)) { members.push(member) @@ -159,7 +166,7 @@ export class Parser { } } } - return { minProperties, maxProperties } + return { minProperties, maxProperties, additionalProperties } } private handleTypeAliasDeclaration(declaration: ts.TypeAliasDeclaration, jsDocs: JsDoc[], entry: JsDoc | undefined) { @@ -634,7 +641,7 @@ export class Parser { const members: Member[] = [] let minProperties = 0 let maxProperties = 0 - let additionalProperties: Type | undefined + let additionalProperties: Type | undefined | boolean for (const element of elements) { if (element.kind === ts.SyntaxKind.PropertySignature) { const property = element as ts.PropertySignature @@ -906,5 +913,5 @@ type MembersInfo = { members: Member[]; minProperties: number; maxProperties: number; - additionalProperties?: Type; + additionalProperties?: Type | boolean; }