Skip to content

Commit bdbe993

Browse files
committed
feat: avoid symbol refs
1 parent 8d65bb2 commit bdbe993

File tree

8 files changed

+57
-11
lines changed

8 files changed

+57
-11
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Usage: typescript-json-schema <path-to-typescript-files-or-tsconfig> <type>
3030
3131
Options:
3232
--refs Create shared ref definitions. [boolean] [default: true]
33+
--avoidSymbolRefs Avoids making refs to type names with symbols. [boolean] [default: false]
3334
--aliasRefs Create shared ref definitions for the type aliases. [boolean] [default: false]
3435
--topRef Create a top-level ref definition. [boolean] [default: false]
3536
--titles Creates titles in the output schema. [boolean] [default: false]

api.md

+11
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,17 @@ export interface MyObject {
891891
```
892892

893893

894+
## [generic-objects](./test/programs/generic-objects)
895+
896+
```ts
897+
type MyObject<Key extends string, Value> = {
898+
[K in Key]: Value
899+
}
900+
901+
export type TheObject = MyObject<'foo'|'bar', 'baz'|'bar'>
902+
```
903+
904+
894905
## [generic-recursive](./test/programs/generic-recursive)
895906
896907
```ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import type { Simplify, Foo } from './types'
2+
3+
export type MyObject = Simplify<Foo>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"definitions": {
4+
"MyObject": {
5+
"type": "object",
6+
"properties": {
7+
"a": {
8+
"type": "number",
9+
"const": 1
10+
}
11+
},
12+
"required": [
13+
"a"
14+
]
15+
}
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export type Simplify<T extends object> = {
2+
[K in keyof T]: T[K]
3+
} & {}
4+
export type Foo = { a: 1 }

test/schema.test.ts

+4
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,10 @@ describe("schema", () => {
300300
describe("generics", () => {
301301
assertSchema("generic-simple", "MyObject");
302302
assertSchema("generic-arrays", "MyObject");
303+
assertSchema("generic-object-index", "*", {
304+
topRef: true,
305+
avoidSymbolRefs: true,
306+
});
303307
assertSchema("generic-multiple", "MyObject");
304308
assertSchema("generic-multiargs", "MyObject");
305309
assertSchema("generic-anonymous", "MyObject");

typescript-json-schema-cli.ts

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export function run() {
88
var args = require("yargs")
99
.usage(helpText)
1010
.demand(2)
11+
.boolean("avoidSymbolRefs").default("avoidSymbolRefs", defaultArgs.avoidSymbolRefs)
12+
.describe("avoidSymbolRefs", "Avoids making refs to type names with symbols.")
1113
.boolean("refs").default("refs", defaultArgs.ref)
1214
.describe("refs", "Create shared ref definitions.")
1315
.boolean("aliasRefs").default("aliasRefs", defaultArgs.aliasRef)
@@ -56,6 +58,7 @@ export function run() {
5658
.argv;
5759

5860
exec(args._[0], args._[1], {
61+
avoidSymbolRefs: args.avoidSymbolRefs,
5962
ref: args.refs,
6063
aliasRef: args.aliasRefs,
6164
topRef: args.topRef,

typescript-json-schema.ts

+14-11
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const NUMERIC_INDEX_PATTERN = "^[0-9]+$";
3737

3838
export function getDefaultArgs(): Args {
3939
return {
40+
avoidSymbolRefs: false,
4041
ref: true,
4142
aliasRef: false,
4243
topRef: false,
@@ -67,6 +68,7 @@ export type ValidationKeywords = {
6768
};
6869

6970
export type Args = {
71+
avoidSymbolRefs: boolean;
7072
ref: boolean;
7173
aliasRef: boolean;
7274
topRef: boolean;
@@ -1180,16 +1182,15 @@ export class JsonSchemaGenerator {
11801182
// Name already assigned?
11811183
return this.typeNamesById[id];
11821184
}
1183-
return this.makeTypeNameUnique(
1184-
typ,
1185-
this.tc
1186-
.typeToString(
1187-
typ,
1188-
undefined,
1189-
ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseFullyQualifiedType
1190-
)
1191-
.replace(REGEX_FILE_NAME_OR_SPACE, "")
1192-
);
1185+
const name = this.tc
1186+
.typeToString(
1187+
typ,
1188+
undefined,
1189+
ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseFullyQualifiedType
1190+
)
1191+
.replace(REGEX_FILE_NAME_OR_SPACE, "")
1192+
1193+
return this.makeTypeNameUnique(typ, name);
11931194
}
11941195

11951196
private makeTypeNameUnique(typ: ts.Type, baseName: string): string {
@@ -1320,8 +1321,10 @@ export class JsonSchemaGenerator {
13201321
}
13211322
}
13221323

1324+
const avoidRef = this.args.avoidSymbolRefs && /[^\d\w_]/.test(fullTypeName)
1325+
asRef = asRef && !avoidRef
13231326
// Handle recursive types
1324-
if (!isRawType || !!typ.aliasSymbol) {
1327+
if (!avoidRef && (!isRawType || !!typ.aliasSymbol)) {
13251328
if (this.recursiveTypeRef.has(fullTypeName) && !forceNotRef) {
13261329
asRef = true;
13271330
} else {

0 commit comments

Comments
 (0)