Skip to content

Commit e68e8e9

Browse files
CaselITdomoritz
authored andcommitted
Correct schema for object with number index (YousefED#248)
* Properly transform object with numeric index (YousefED#245) * Added tests and fixed failing tests (YousefED#245) * remove the compiled files changes
1 parent b50fdf7 commit e68e8e9

File tree

7 files changed

+65
-6
lines changed

7 files changed

+65
-6
lines changed

test/programs/array-types/main.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
interface MyArray {
2-
[index: number]: string | number;
3-
}
1+
type MyArray = Array<string | number>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
interface Target {
2+
objAnonymous: {
3+
[index: number]: number;
4+
};
5+
objInterface: IndexInterface;
6+
}
7+
interface IndexInterface {
8+
[index: number]: number;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"properties": {
4+
"objAnonymous": {
5+
"additionalProperties": false,
6+
"patternProperties": {
7+
"^[0-9]+$": {
8+
"type": "number"
9+
}
10+
},
11+
"type": "object"
12+
},
13+
"objInterface": {
14+
"additionalProperties": false,
15+
"patternProperties": {
16+
"^[0-9]+$": {
17+
"type": "number"
18+
}
19+
},
20+
"type": "object"
21+
}
22+
},
23+
"type": "object"
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
interface IndexInterface {
2+
[index: number]: number;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"additionalProperties": false,
4+
"patternProperties": {
5+
"^[0-9]+$": {
6+
"type": "number"
7+
}
8+
},
9+
"type": "object"
10+
}

test/schema.test.ts

+5
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,11 @@ describe("schema", () => {
307307
id: "someSchemaId"
308308
});
309309
});
310+
311+
describe("object index", () => {
312+
assertSchema("object-numeric-index", "IndexInterface");
313+
assertSchema("object-numeric-index-as-property", "Target", { required: false });
314+
});
310315
});
311316

312317
describe("tsconfig.json", () => {

typescript-json-schema.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const vm = require("vm");
1111
const REGEX_FILE_NAME_OR_SPACE = /(\bimport\(".*?"\)|".*?")\.| /g;
1212
const REGEX_TSCONFIG_NAME = /^.*\.json$/;
1313
const REGEX_TJS_JSDOC = /^-([\w]+)\s+(\S|\S[\s\S]*\S)\s*$/g;
14+
const NUMERIC_INDEX_PATTERN = "^[0-9]+$";
1415

1516
export function getDefaultArgs(): Args {
1617
return {
@@ -88,7 +89,7 @@ export type Definition = {
8889
propertyOrder?: string[],
8990
properties?: {[key: string]: any},
9091
defaultProperties?: string[],
91-
92+
patternProperties?: {[pattern: string]: Definition},
9293
typeof?: "function"
9394
};
9495

@@ -419,8 +420,17 @@ export class JsonSchemaGenerator {
419420
definition.type = typeof value;
420421
definition.enum = [ value ];
421422
} else if (arrayType !== undefined) {
422-
definition.type = "array";
423-
definition.items = this.getTypeDefinition(arrayType);
423+
if ((propertyType.flags & ts.TypeFlags.Object) &&
424+
((propertyType as ts.ObjectType).objectFlags & (ts.ObjectFlags.Anonymous | ts.ObjectFlags.Interface))) {
425+
definition.type = "object";
426+
definition.additionalProperties = false;
427+
definition.patternProperties = {
428+
[NUMERIC_INDEX_PATTERN]: this.getTypeDefinition(arrayType)
429+
};
430+
} else {
431+
definition.type = "array";
432+
definition.items = this.getTypeDefinition(arrayType);
433+
}
424434
} else {
425435
// Report that type could not be processed
426436
const error = new TypeError("Unsupported type: " + propertyTypeString);

0 commit comments

Comments
 (0)