Skip to content

Commit

Permalink
feat: avoid symbol refs
Browse files Browse the repository at this point in the history
  • Loading branch information
qwelias committed Jun 29, 2023
1 parent 8d65bb2 commit bdbe993
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 11 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Usage: typescript-json-schema <path-to-typescript-files-or-tsconfig> <type>
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]
Expand Down
11 changes: 11 additions & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,17 @@ export interface MyObject {
```


## [generic-objects](./test/programs/generic-objects)

```ts
type MyObject<Key extends string, Value> = {
[K in Key]: Value
}

export type TheObject = MyObject<'foo'|'bar', 'baz'|'bar'>
```
## [generic-recursive](./test/programs/generic-recursive)
```ts
Expand Down
3 changes: 3 additions & 0 deletions test/programs/generic-object-index/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { Simplify, Foo } from './types'

export type MyObject = Simplify<Foo>
17 changes: 17 additions & 0 deletions test/programs/generic-object-index/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"MyObject": {
"type": "object",
"properties": {
"a": {
"type": "number",
"const": 1
}
},
"required": [
"a"
]
}
}
}
4 changes: 4 additions & 0 deletions test/programs/generic-object-index/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type Simplify<T extends object> = {
[K in keyof T]: T[K]
} & {}
export type Foo = { a: 1 }
4 changes: 4 additions & 0 deletions test/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
3 changes: 3 additions & 0 deletions typescript-json-schema-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down
25 changes: 14 additions & 11 deletions typescript-json-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const NUMERIC_INDEX_PATTERN = "^[0-9]+$";

export function getDefaultArgs(): Args {
return {
avoidSymbolRefs: false,
ref: true,
aliasRef: false,
topRef: false,
Expand Down Expand Up @@ -67,6 +68,7 @@ export type ValidationKeywords = {
};

export type Args = {
avoidSymbolRefs: boolean;
ref: boolean;
aliasRef: boolean;
topRef: boolean;
Expand Down Expand Up @@ -1180,16 +1182,15 @@ export class JsonSchemaGenerator {
// Name already assigned?
return this.typeNamesById[id];
}
return this.makeTypeNameUnique(
typ,
this.tc
.typeToString(
typ,
undefined,
ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseFullyQualifiedType
)
.replace(REGEX_FILE_NAME_OR_SPACE, "")
);
const name = this.tc
.typeToString(
typ,
undefined,
ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseFullyQualifiedType
)
.replace(REGEX_FILE_NAME_OR_SPACE, "")

return this.makeTypeNameUnique(typ, name);
}

private makeTypeNameUnique(typ: ts.Type, baseName: string): string {
Expand Down Expand Up @@ -1320,8 +1321,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 {
Expand Down

0 comments on commit bdbe993

Please sign in to comment.