From 6ab5ebdf892d280251ff39fc289d7e178e13a638 Mon Sep 17 00:00:00 2001 From: Gethin Davies Date: Fri, 31 Jan 2025 13:35:49 +0000 Subject: [PATCH 1/2] Add failing test --- test/valid-data-type.test.ts | 2 ++ .../type-indexed-access-object-key-enum/main.ts | 11 +++++++++++ .../type-indexed-access-object-key-enum/schema.json | 12 ++++++++++++ .../type-indexed-access-object-key-union/main.ts | 8 ++++++++ .../type-indexed-access-object-key-union/schema.json | 12 ++++++++++++ 5 files changed, 45 insertions(+) create mode 100644 test/valid-data/type-indexed-access-object-key-enum/main.ts create mode 100644 test/valid-data/type-indexed-access-object-key-enum/schema.json create mode 100644 test/valid-data/type-indexed-access-object-key-union/main.ts create mode 100644 test/valid-data/type-indexed-access-object-key-union/schema.json diff --git a/test/valid-data-type.test.ts b/test/valid-data-type.test.ts index 8e06518fc..1fb40e209 100644 --- a/test/valid-data-type.test.ts +++ b/test/valid-data-type.test.ts @@ -83,6 +83,8 @@ describe("valid-data-type", () => { it("type-indexed-access-object-1", assertValidSchema("type-indexed-access-object-1", "MyType")); it("type-indexed-access-object-2", assertValidSchema("type-indexed-access-object-2", "MyType")); it("type-indexed-access-keyof", assertValidSchema("type-indexed-access-keyof", "MyType")); + it("type-indexed-access-object-key-enum", assertValidSchema("type-indexed-access-object-key-enum", "Value")); + it("type-indexed-access-object-key-union", assertValidSchema("type-indexed-access-object-key-union", "Value")); it("type-indexed-circular-access", assertValidSchema("type-indexed-circular-access", "*")); it("type-indexed-circular", assertValidSchema("type-indexed-circular", "MyType")); it("type-keyof-tuple", assertValidSchema("type-keyof-tuple", "MyType")); diff --git a/test/valid-data/type-indexed-access-object-key-enum/main.ts b/test/valid-data/type-indexed-access-object-key-enum/main.ts new file mode 100644 index 000000000..beb568d42 --- /dev/null +++ b/test/valid-data/type-indexed-access-object-key-enum/main.ts @@ -0,0 +1,11 @@ +enum Variant { + A = 0, + B = "STR", +} + +type KVMap = { + [Variant.A]: boolean; + [Variant.B]: number; +}; + +export type Value = KVMap[Variant]; diff --git a/test/valid-data/type-indexed-access-object-key-enum/schema.json b/test/valid-data/type-indexed-access-object-key-enum/schema.json new file mode 100644 index 000000000..18312fe49 --- /dev/null +++ b/test/valid-data/type-indexed-access-object-key-enum/schema.json @@ -0,0 +1,12 @@ +{ + "$ref": "#/definitions/Value", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "Value": { + "type": [ + "boolean", + "number" + ] + } + } +} diff --git a/test/valid-data/type-indexed-access-object-key-union/main.ts b/test/valid-data/type-indexed-access-object-key-union/main.ts new file mode 100644 index 000000000..dfe7b9d6e --- /dev/null +++ b/test/valid-data/type-indexed-access-object-key-union/main.ts @@ -0,0 +1,8 @@ +type Variant = 0 | "ONE"; + +type KVMap = { + 0: boolean; + ONE: number; +}; + +export type Value = KVMap[Variant]; diff --git a/test/valid-data/type-indexed-access-object-key-union/schema.json b/test/valid-data/type-indexed-access-object-key-union/schema.json new file mode 100644 index 000000000..18312fe49 --- /dev/null +++ b/test/valid-data/type-indexed-access-object-key-union/schema.json @@ -0,0 +1,12 @@ +{ + "$ref": "#/definitions/Value", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "Value": { + "type": [ + "boolean", + "number" + ] + } + } +} From 928d69044e22da8e3b01308491fafe672301639c Mon Sep 17 00:00:00 2001 From: Gethin Davies Date: Fri, 31 Jan 2025 13:40:05 +0000 Subject: [PATCH 2/2] fix: allow enums and unions as record indexed access keys --- src/NodeParser/IndexedAccessTypeNodeParser.ts | 4 +++- src/Utils/typeKeys.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/NodeParser/IndexedAccessTypeNodeParser.ts b/src/NodeParser/IndexedAccessTypeNodeParser.ts index d7a481350..ea0ac5e4e 100644 --- a/src/NodeParser/IndexedAccessTypeNodeParser.ts +++ b/src/NodeParser/IndexedAccessTypeNodeParser.ts @@ -12,6 +12,7 @@ import { UnionType } from "../Type/UnionType.js"; import { derefType } from "../Utils/derefType.js"; import { getTypeByKey } from "../Utils/typeKeys.js"; import { LogicError } from "../Error/Errors.js"; +import { EnumType } from "../Type/EnumType.js"; export class IndexedAccessTypeNodeParser implements SubNodeParser { public constructor( @@ -58,7 +59,8 @@ export class IndexedAccessTypeNodeParser implements SubNodeParser { return new NeverType(); } - const indexTypes = indexType instanceof UnionType ? indexType.getTypes() : [indexType]; + const indexTypes = + indexType instanceof UnionType || indexType instanceof EnumType ? indexType.getTypes() : [indexType]; const propertyTypes = indexTypes.map((type) => { if (!(type instanceof LiteralType || type instanceof StringType || type instanceof NumberType)) { throw new LogicError( diff --git a/src/Utils/typeKeys.ts b/src/Utils/typeKeys.ts index 1581b2107..9c2596b81 100644 --- a/src/Utils/typeKeys.ts +++ b/src/Utils/typeKeys.ts @@ -97,7 +97,7 @@ export function getTypeByKey(type: BaseType, index: LiteralType | StringType | N } if (type instanceof ObjectType) { if (index instanceof LiteralType) { - const property = type.getProperties().find((it) => it.getName() === index.getValue()); + const property = type.getProperties().find((it) => it.getName() === index.getName()); if (property) { const propertyType = property.getType(); if (propertyType === undefined) {