Skip to content

Commit 3c112c5

Browse files
authored
Merge pull request #1937 from vega/next
Release
2 parents 6b6c47e + 9043546 commit 3c112c5

File tree

11 files changed

+168
-124
lines changed

11 files changed

+168
-124
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,7 @@ jobs:
1212
test:
1313
name: Test
1414

15-
strategy:
16-
fail-fast: false
17-
matrix:
18-
os: [ubuntu-latest, windows-latest]
19-
20-
runs-on: ${{ matrix.os }}
15+
runs-on: ubuntu-latest
2116

2217
steps:
2318
- uses: actions/checkout@v4
File renamed without changes.

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"types": "dist/index.d.ts",
77
"type": "module",
88
"bin": {
9-
"ts-json-schema-generator": "./bin/ts-json-schema-generator"
9+
"ts-json-schema-generator": "./bin/ts-json-schema-generator.js"
1010
},
1111
"files": [
1212
"dist",
@@ -59,8 +59,8 @@
5959
"@babel/core": "^7.24.4",
6060
"@babel/preset-env": "^7.24.4",
6161
"@babel/preset-typescript": "^7.24.1",
62-
"@eslint/js": "^9.0.0",
63-
"@types/eslint": "^8.56.9",
62+
"@eslint/js": "^9.1.1",
63+
"@types/eslint": "^8.56.10",
6464
"@types/glob": "^8.1.0",
6565
"@types/jest": "^29.5.12",
6666
"@types/node": "^20.12.7",
@@ -70,14 +70,14 @@
7070
"auto": "^11.1.6",
7171
"chai": "^5.1.0",
7272
"cross-env": "^7.0.3",
73-
"eslint": "^9.0.0",
73+
"eslint": "^9.1.0",
7474
"eslint-config-prettier": "^9.1.0",
7575
"eslint-plugin-prettier": "^5.1.3",
7676
"jest": "^29.7.0",
7777
"jest-junit": "^16.0.0",
7878
"prettier": "^3.2.5",
7979
"tsx": "^4.7.2",
80-
"typescript-eslint": "^7.7.0",
80+
"typescript-eslint": "^7.7.1",
8181
"vega": "^5.28.0",
8282
"vega-lite": "^5.18.0"
8383
},

src/NodeParser/MappedTypeNodeParser.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { derefAnnotatedType, derefType } from "../Utils/derefType.js";
1818
import { getKey } from "../Utils/nodeKey.js";
1919
import { preserveAnnotation } from "../Utils/preserveAnnotation.js";
2020
import { removeUndefined } from "../Utils/removeUndefined.js";
21+
import { uniqueTypeArray } from "../Utils/uniqueTypeArray.js";
2122

2223
export class MappedTypeNodeParser implements SubNodeParser {
2324
public constructor(
@@ -94,16 +95,11 @@ export class MappedTypeNodeParser implements SubNodeParser {
9495
if (!node.nameType) {
9596
return rawKey;
9697
}
97-
const key = derefType(
98-
this.childNodeParser.createType(node.nameType, this.createSubContext(node, rawKey, context)),
99-
);
100-
101-
return key;
98+
return derefType(this.childNodeParser.createType(node.nameType, this.createSubContext(node, rawKey, context)));
10299
}
103100

104101
protected getProperties(node: ts.MappedTypeNode, keyListType: UnionType, context: Context): ObjectProperty[] {
105-
return keyListType
106-
.getTypes()
102+
return uniqueTypeArray(keyListType.getFlattenedTypes(derefType))
107103
.filter((type): type is LiteralType => type instanceof LiteralType)
108104
.map((type) => [type, this.mapKey(node, type, context)])
109105
.filter((value): value is [LiteralType, LiteralType] => value[1] instanceof LiteralType)

src/Type/UnionType.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { BaseType } from "./BaseType.js";
22
import { uniqueTypeArray } from "../Utils/uniqueTypeArray.js";
33
import { NeverType } from "./NeverType.js";
4-
import { derefType } from "../Utils/derefType.js";
4+
import { derefAliasedType, derefType, isHiddenType } from "../Utils/derefType.js";
55

66
export class UnionType extends BaseType {
77
private readonly types: BaseType[];
@@ -56,4 +56,19 @@ export class UnionType extends BaseType {
5656
}
5757
}
5858
}
59+
60+
/**
61+
* Get the types in this union as a flat list.
62+
*/
63+
public getFlattenedTypes(deref: (type: BaseType) => BaseType = derefAliasedType): BaseType[] {
64+
return this.getTypes()
65+
.filter((t) => !isHiddenType(t))
66+
.map(deref)
67+
.flatMap((t) => {
68+
if (t instanceof UnionType) {
69+
return t.getFlattenedTypes(deref);
70+
}
71+
return t;
72+
});
73+
}
5974
}

src/TypeFormatter/LiteralUnionTypeFormatter.ts

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { LiteralType, LiteralValue } from "../Type/LiteralType.js";
66
import { NullType } from "../Type/NullType.js";
77
import { StringType } from "../Type/StringType.js";
88
import { UnionType } from "../Type/UnionType.js";
9-
import { derefAliasedType, isHiddenType } from "../Utils/derefType.js";
109
import { typeName } from "../Utils/typeName.js";
1110
import { uniqueArray } from "../Utils/uniqueArray.js";
1211

@@ -20,10 +19,10 @@ export class LiteralUnionTypeFormatter implements SubTypeFormatter {
2019
let allStrings = true;
2120
let hasNull = false;
2221

23-
const flattenedTypes = flattenTypes(type);
22+
const literals = type.getFlattenedTypes();
2423

2524
// filter out String types since we need to be more careful about them
26-
const types = flattenedTypes.filter((t) => {
25+
const types = literals.filter((t) => {
2726
if (t instanceof StringType) {
2827
hasString = true;
2928
preserveLiterals = preserveLiterals || t.getPreserveLiterals();
@@ -70,23 +69,10 @@ export class LiteralUnionTypeFormatter implements SubTypeFormatter {
7069
}
7170
}
7271

73-
function flattenTypes(type: UnionType): (StringType | LiteralType | NullType)[] {
74-
return type
75-
.getTypes()
76-
.filter((t) => !isHiddenType(t))
77-
.map(derefAliasedType)
78-
.flatMap((t) => {
79-
if (t instanceof UnionType) {
80-
return flattenTypes(t);
81-
}
82-
return t as StringType | LiteralType | NullType;
83-
});
84-
}
85-
8672
export function isLiteralUnion(type: UnionType): boolean {
87-
return flattenTypes(type).every(
88-
(item) => item instanceof LiteralType || item instanceof NullType || item instanceof StringType,
89-
);
73+
return type
74+
.getFlattenedTypes()
75+
.every((item) => item instanceof LiteralType || item instanceof NullType || item instanceof StringType);
9076
}
9177

9278
function getLiteralValue(value: LiteralType | NullType): LiteralValue | null {

test/valid-data-type.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ describe("valid-data-type", () => {
102102
it("type-mapped-additional-props", assertValidSchema("type-mapped-additional-props", "MyObject"));
103103
it("type-mapped-array", assertValidSchema("type-mapped-array", "MyObject"));
104104
it("type-mapped-union-intersection", assertValidSchema("type-mapped-union-intersection", "MyObject"));
105+
it("type-mapped-union-union", assertValidSchema("type-mapped-union-union", "MyType"));
105106
it("type-mapped-enum", assertValidSchema("type-mapped-enum", "MyObject"));
106107
it("type-mapped-enum-optional", assertValidSchema("type-mapped-enum-optional", "MyObject"));
107108
it("type-mapped-enum-null", assertValidSchema("type-mapped-enum-null", "MyObject"));
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
type MyType1 = "s1";
2+
type MyType2 = MyType1 | "s2" | "s3";
3+
type MyType3 = MyType2 | "s4" | "s5";
4+
type MyType10 = MyType3 | MyType2 | "s6";
5+
6+
export type MyType = Record<MyType10, string>;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"$ref": "#/definitions/MyType",
3+
"$schema": "http://json-schema.org/draft-07/schema#",
4+
"definitions": {
5+
"MyType": {
6+
"additionalProperties": {
7+
"type": "string"
8+
},
9+
"properties": {
10+
"s1": {
11+
"type": "string"
12+
},
13+
"s2": {
14+
"type": "string"
15+
},
16+
"s3": {
17+
"type": "string"
18+
},
19+
"s4": {
20+
"type": "string"
21+
},
22+
"s5": {
23+
"type": "string"
24+
},
25+
"s6": {
26+
"type": "string"
27+
}
28+
},
29+
"required": [
30+
"s1",
31+
"s2",
32+
"s3",
33+
"s4",
34+
"s5",
35+
"s6"
36+
],
37+
"type": "object"
38+
}
39+
}
40+
}

tsconfig.eslint.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"extends": "./tsconfig.json",
3-
"include": ["src/**/*.ts", "factory/**/*.ts", "test/**/*.test.ts", "test/utils.ts"]
3+
"include": ["src/**/*.ts", "factory/**/*.ts", "test/**/*.test.ts", "test/utils.ts", "bin/ts-json-schema-generator.js"]
44
}

0 commit comments

Comments
 (0)