diff --git a/src/NodeParser/TypeLiteralNodeParser.ts b/src/NodeParser/TypeLiteralNodeParser.ts index 4c1b4a5ea..e5098b3a1 100644 --- a/src/NodeParser/TypeLiteralNodeParser.ts +++ b/src/NodeParser/TypeLiteralNodeParser.ts @@ -93,8 +93,10 @@ export class TypeLiteralNodeParser implements SubNodeParser { } catch { // When propertyName was programmatically created, it doesn't have a source file. // Then, getText() will throw an error. But, for programmatically created nodes,` - // `escapedText` is available. - return (propertyName as ts.Identifier).escapedText as string; + // `escapedText` or `text` is available. + // Only `text` will be available when propertyName contains strange characters and it cannot be escaped + // or if it is a number. + return ((propertyName as ts.Identifier).escapedText as string) ?? (propertyName as ts.StringLiteral).text; } } } diff --git a/test/valid-data-struct.test.ts b/test/valid-data-struct.test.ts index 0e8b7a27f..9cdb5463c 100644 --- a/test/valid-data-struct.test.ts +++ b/test/valid-data-struct.test.ts @@ -36,4 +36,6 @@ describe("valid-data-struct", () => { it("structure-anonymous", assertValidSchema("structure-anonymous", "MyObject")); it("structure-recursion", assertValidSchema("structure-recursion", "MyObject")); it("structure-extra-props", assertValidSchema("structure-extra-props", "MyObject")); + + it("string-literal-property-names", assertValidSchema("string-literal-property-names", "*")); }); diff --git a/test/valid-data/string-literal-property-names/main.ts b/test/valid-data/string-literal-property-names/main.ts new file mode 100644 index 000000000..1455efa22 --- /dev/null +++ b/test/valid-data/string-literal-property-names/main.ts @@ -0,0 +1,38 @@ +// Class props has only implicit types! +export class MyClass { + PROP_1 = ''; + "PROP_2" = ''; + "PROP.3" = ''; + "{PROP_4}" = ''; + "400" = ''; + 500 = ''; + '' = ''; + CHILD = { + PROP_1: '', + "PROP_2": '', + "PROP.3": '', + "{PROP_4}": '', + "400": '', + 500: '', + '': '', + }; +} + +export interface MyInterface { + PROP_1: string; + "PROP_2": string; + "PROP.3": string; + "{PROP_4}": string; + "400": string; + 500: string; + '': string; + CHILD : { + PROP_1: string, + "PROP_2": string, + "PROP.3": string, + "{PROP_4}": string, + "400": string, + 500: string, + '': string + }; +} diff --git a/test/valid-data/string-literal-property-names/schema.json b/test/valid-data/string-literal-property-names/schema.json new file mode 100644 index 000000000..27291434f --- /dev/null +++ b/test/valid-data/string-literal-property-names/schema.json @@ -0,0 +1,151 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "MyClass": { + "additionalProperties": false, + "properties": { + "": { + "type": "string" + }, + "400": { + "type": "string" + }, + "500": { + "type": "string" + }, + "CHILD": { + "additionalProperties": false, + "properties": { + "": { + "type": "string" + }, + "400": { + "type": "string" + }, + "500": { + "type": "string" + }, + "PROP.3": { + "type": "string" + }, + "PROP_1": { + "type": "string" + }, + "PROP_2": { + "type": "string" + }, + "{PROP_4}": { + "type": "string" + } + }, + "required": [ + "PROP_1", + "PROP_2", + "PROP.3", + "{PROP_4}", + "400", + "500", + "" + ], + "type": "object" + }, + "PROP.3": { + "type": "string" + }, + "PROP_1": { + "type": "string" + }, + "PROP_2": { + "type": "string" + }, + "{PROP_4}": { + "type": "string" + } + }, + "required": [ + "PROP_1", + "PROP_2", + "PROP.3", + "{PROP_4}", + "400", + "500", + "", + "CHILD" + ], + "type": "object" + }, + "MyInterface": { + "additionalProperties": false, + "properties": { + "": { + "type": "string" + }, + "400": { + "type": "string" + }, + "500": { + "type": "string" + }, + "CHILD": { + "additionalProperties": false, + "properties": { + "": { + "type": "string" + }, + "400": { + "type": "string" + }, + "500": { + "type": "string" + }, + "PROP.3": { + "type": "string" + }, + "PROP_1": { + "type": "string" + }, + "PROP_2": { + "type": "string" + }, + "{PROP_4}": { + "type": "string" + } + }, + "required": [ + "PROP_1", + "PROP_2", + "PROP.3", + "{PROP_4}", + "400", + "500", + "" + ], + "type": "object" + }, + "PROP.3": { + "type": "string" + }, + "PROP_1": { + "type": "string" + }, + "PROP_2": { + "type": "string" + }, + "{PROP_4}": { + "type": "string" + } + }, + "required": [ + "PROP_1", + "PROP_2", + "PROP.3", + "{PROP_4}", + "400", + "500", + "", + "CHILD" + ], + "type": "object" + } + } +} \ No newline at end of file