Skip to content

Commit f38327e

Browse files
netanel-mcenetanel-mce
andauthored
Correct schema for mapped object with other keys (YousefED#567)
* allow-extra-props-where-pattern-properties-not-empty * object mapped and other keys * docs * remove unnecessary changes * remove unnecessary changes 2 * remove unnecessary changes 3 * remove unnecessary changes 4 * fix auto test * fix comment * 0.60.0 * Back to 0.59.0 --------- Co-authored-by: netanel-mce <[email protected]>
1 parent 3662786 commit f38327e

File tree

5 files changed

+48
-4
lines changed

5 files changed

+48
-4
lines changed

api.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,17 @@ interface SomeOtherDefinition {
12851285
```
12861286

12871287

1288+
## [numeric-keys-and-others](./test/programs/numeric-keys-and-others)
1289+
1290+
```ts
1291+
interface NumericKeysAndOthers {
1292+
[key: number]: number;
1293+
a: string;
1294+
b: boolean;
1295+
}
1296+
```
1297+
1298+
12881299
## [object-numeric-index](./test/programs/object-numeric-index)
12891300

12901301
```ts
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
interface NumericKeysAndOthers {
2+
[key: number]: number;
3+
a: string;
4+
b: boolean;
5+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"additionalProperties": false,
4+
"patternProperties": {
5+
"^[0-9]+$": {
6+
"type": "number"
7+
}
8+
},
9+
"properties": {
10+
"a": {
11+
"type": "string"
12+
},
13+
"b": {
14+
"type": "boolean"
15+
}
16+
},
17+
"required": [
18+
"a",
19+
"b"
20+
],
21+
"type": "object"
22+
}

test/schema.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ describe("schema", () => {
379379
assertSchema("array-empty", "MyEmptyArray");
380380
assertSchema("map-types", "MyObject");
381381
assertSchema("extra-properties", "MyObject");
382+
assertSchema("numeric-keys-and-others", "NumericKeysAndOthers");
382383
});
383384

384385
describe("string literals", () => {

typescript-json-schema.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,9 @@ export class JsonSchemaGenerator {
721721
definition.patternProperties = {
722722
[NUMERIC_INDEX_PATTERN]: this.getTypeDefinition(arrayType),
723723
};
724+
if (!!Array.from((<any>propertyType).members)?.find((member: [string]) => member[0] !== "__index")) {
725+
this.getClassDefinition(propertyType, definition);
726+
}
724727
} else {
725728
definition.type = "array";
726729
if (!definition.items) {
@@ -1079,8 +1082,8 @@ export class JsonSchemaGenerator {
10791082
}
10801083
const indexSymbol: ts.Symbol = (<any>indexSignature.parameters[0]).symbol;
10811084
const indexType = this.tc.getTypeOfSymbolAtLocation(indexSymbol, node);
1082-
const isStringIndexed = indexType.flags === ts.TypeFlags.String;
1083-
if (indexType.flags !== ts.TypeFlags.Number && !isStringIndexed) {
1085+
const isIndexedObject = indexType.flags === ts.TypeFlags.String || indexType.flags === ts.TypeFlags.Number;
1086+
if (indexType.flags !== ts.TypeFlags.Number && !isIndexedObject) {
10841087
throw new Error(
10851088
"Not supported: IndexSignatureDeclaration with index symbol other than a number or a string"
10861089
);
@@ -1105,9 +1108,11 @@ export class JsonSchemaGenerator {
11051108
if (!def) {
11061109
def = this.getTypeDefinition(typ, undefined, "anyOf");
11071110
}
1108-
if (isStringIndexed) {
1111+
if (isIndexedObject) {
11091112
definition.type = "object";
1110-
definition.additionalProperties = def;
1113+
if (!Object.keys(definition.patternProperties || {}).length) {
1114+
definition.additionalProperties = def;
1115+
}
11111116
} else {
11121117
definition.type = "array";
11131118
if (!definition.items) {

0 commit comments

Comments
 (0)