From 3268f3b15f3606990e35ac7e10f5101019d727df Mon Sep 17 00:00:00 2001 From: chatcan Date: Sat, 2 Sep 2023 04:01:16 +0800 Subject: [PATCH] fix #426 (#569) * fix https://github.com/YousefED/typescript-json-schema/issues/426 * fix https://github.com/YousefED/typescript-json-schema/issues/426 --------- Co-authored-by: can --- test/programs/string-template-literal/main.ts | 11 ++++ .../string-template-literal/schema.json | 57 +++++++++++++++++++ test/schema.test.ts | 4 ++ typescript-json-schema.ts | 38 +++++++++++++ 4 files changed, 110 insertions(+) create mode 100644 test/programs/string-template-literal/main.ts create mode 100644 test/programs/string-template-literal/schema.json diff --git a/test/programs/string-template-literal/main.ts b/test/programs/string-template-literal/main.ts new file mode 100644 index 00000000..4b0745b0 --- /dev/null +++ b/test/programs/string-template-literal/main.ts @@ -0,0 +1,11 @@ +interface MyObject { + a: `@${string}`, + b: `@${number}`, + c: `@${bigint}`, + d: `@${boolean}`, + e: `@${undefined}`, + f: `@${null}`, + g: `${string}@`, + h: `${number}@`, + i: `${string}@${number}`, +} \ No newline at end of file diff --git a/test/programs/string-template-literal/schema.json b/test/programs/string-template-literal/schema.json new file mode 100644 index 00000000..cc39dd2c --- /dev/null +++ b/test/programs/string-template-literal/schema.json @@ -0,0 +1,57 @@ +{ + "type": "object", + "properties": { + "a": { + "type": "string", + "pattern": "^@.*$" + }, + "b": { + "type": "string", + "pattern": "^@[0-9]*$" + }, + "c": { + "type": "string", + "pattern": "^@[0-9]*$" + }, + "d": { + "enum": [ + "@false", + "@true" + ], + "type": "string" + }, + "e": { + "type": "string", + "const": "@undefined" + }, + "f": { + "type": "string", + "const": "@null" + }, + "g": { + "type": "string", + "pattern": "^.*@$" + }, + "h": { + "type": "string", + "pattern": "^[0-9]*@$" + }, + "i": { + "type": "string", + "pattern": "^.*@[0-9]*$" + } + }, + "additionalProperties": false, + "required": [ + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i" + ], + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/test/schema.test.ts b/test/schema.test.ts index dc1f4e86..14069c50 100644 --- a/test/schema.test.ts +++ b/test/schema.test.ts @@ -387,6 +387,10 @@ describe("schema", () => { assertSchema("string-literals-inline", "MyObject"); }); + describe("template string", () => { + assertSchema("string-template-literal", "MyObject"); + }); + describe("custom dates", () => { assertSchema("custom-dates", "foo.Bar"); }); diff --git a/typescript-json-schema.ts b/typescript-json-schema.ts index 8d1212b8..2337b64c 100644 --- a/typescript-json-schema.ts +++ b/typescript-json-schema.ts @@ -724,6 +724,44 @@ export class JsonSchemaGenerator { if (!!Array.from((propertyType).members)?.find((member: [string]) => member[0] !== "__index")) { this.getClassDefinition(propertyType, definition); } + } else if (propertyType.flags & ts.TypeFlags.TemplateLiteral) { + definition.type = "string"; + // @ts-ignore + const {texts, types} = propertyType; + const pattern = []; + for (let i = 0; i < texts.length; i++) { + const text = texts[i]; + const type = types[i]; + + if (i === 0) { + pattern.push(`^`); + } + + if (type) { + if (type.flags & ts.TypeFlags.String) { + pattern.push(`${text}.*`); + } + + if (type.flags & ts.TypeFlags.Number + || type.flags & ts.TypeFlags.BigInt) { + pattern.push(`${text}[0-9]*`); + } + + if (type.flags & ts.TypeFlags.Undefined) { + pattern.push(`${text}undefined`); + } + + if (type.flags & ts.TypeFlags.Null) { + pattern.push(`${text}null`); + } + } + + + if (i === texts.length - 1) { + pattern.push(`${text}$`); + } + } + definition.pattern = pattern.join(""); } else { definition.type = "array"; if (!definition.items) {