diff --git a/README.md b/README.md index f757a833..8bcff630 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Usage: typescript-json-schema Options: --refs Create shared ref definitions. [boolean] [default: true] + --avoidSymbolRefs Avoids making refs to type names with symbols. [boolean] [default: false] --aliasRefs Create shared ref definitions for the type aliases. [boolean] [default: false] --topRef Create a top-level ref definition. [boolean] [default: false] --titles Creates titles in the output schema. [boolean] [default: false] diff --git a/api.md b/api.md index 59479180..96ab9ceb 100644 --- a/api.md +++ b/api.md @@ -891,6 +891,17 @@ export interface MyObject { ``` +## [generic-objects](./test/programs/generic-objects) + +```ts +type MyObject = { + [K in Key]: Value +} + +export type TheObject = MyObject<'foo'|'bar', 'baz'|'bar'> +``` + + ## [generic-recursive](./test/programs/generic-recursive) ```ts diff --git a/test/programs/generic-object-index/main.ts b/test/programs/generic-object-index/main.ts new file mode 100644 index 00000000..b384e9cc --- /dev/null +++ b/test/programs/generic-object-index/main.ts @@ -0,0 +1,3 @@ +import type { Simplify, Foo } from './types' + +export type MyObject = Simplify \ No newline at end of file diff --git a/test/programs/generic-object-index/schema.json b/test/programs/generic-object-index/schema.json new file mode 100644 index 00000000..61a7b79e --- /dev/null +++ b/test/programs/generic-object-index/schema.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "MyObject": { + "type": "object", + "properties": { + "a": { + "type": "number", + "const": 1 + } + }, + "required": [ + "a" + ] + } + } +} \ No newline at end of file diff --git a/test/programs/generic-object-index/types.ts b/test/programs/generic-object-index/types.ts new file mode 100644 index 00000000..8afa4055 --- /dev/null +++ b/test/programs/generic-object-index/types.ts @@ -0,0 +1,4 @@ +export type Simplify = { + [K in keyof T]: T[K] +} & {} +export type Foo = { a: 1 } diff --git a/test/schema.test.ts b/test/schema.test.ts index 15b5fd9c..f163a561 100644 --- a/test/schema.test.ts +++ b/test/schema.test.ts @@ -300,6 +300,10 @@ describe("schema", () => { describe("generics", () => { assertSchema("generic-simple", "MyObject"); assertSchema("generic-arrays", "MyObject"); + assertSchema("generic-object-index", "*", { + topRef: true, + avoidSymbolRefs: true, + }); assertSchema("generic-multiple", "MyObject"); assertSchema("generic-multiargs", "MyObject"); assertSchema("generic-anonymous", "MyObject"); diff --git a/typescript-json-schema-cli.ts b/typescript-json-schema-cli.ts index 11eb182b..97f14c5a 100644 --- a/typescript-json-schema-cli.ts +++ b/typescript-json-schema-cli.ts @@ -8,6 +8,8 @@ export function run() { var args = require("yargs") .usage(helpText) .demand(2) + .boolean("avoidSymbolRefs").default("avoidSymbolRefs", defaultArgs.avoidSymbolRefs) + .describe("avoidSymbolRefs", "Avoids making refs to type names with symbols.") .boolean("refs").default("refs", defaultArgs.ref) .describe("refs", "Create shared ref definitions.") .boolean("aliasRefs").default("aliasRefs", defaultArgs.aliasRef) @@ -56,6 +58,7 @@ export function run() { .argv; exec(args._[0], args._[1], { + avoidSymbolRefs: args.avoidSymbolRefs, ref: args.refs, aliasRef: args.aliasRefs, topRef: args.topRef, diff --git a/typescript-json-schema.ts b/typescript-json-schema.ts index a9939c26..a0ce7371 100644 --- a/typescript-json-schema.ts +++ b/typescript-json-schema.ts @@ -37,6 +37,7 @@ const NUMERIC_INDEX_PATTERN = "^[0-9]+$"; export function getDefaultArgs(): Args { return { + avoidSymbolRefs: false, ref: true, aliasRef: false, topRef: false, @@ -67,6 +68,7 @@ export type ValidationKeywords = { }; export type Args = { + avoidSymbolRefs: boolean; ref: boolean; aliasRef: boolean; topRef: boolean; @@ -1320,8 +1322,10 @@ export class JsonSchemaGenerator { } } + const avoidRef = this.args.avoidSymbolRefs && /[^\d\w_]/.test(fullTypeName); + asRef = asRef && !avoidRef; // Handle recursive types - if (!isRawType || !!typ.aliasSymbol) { + if (!avoidRef && (!isRawType || !!typ.aliasSymbol)) { if (this.recursiveTypeRef.has(fullTypeName) && !forceNotRef) { asRef = true; } else {