diff --git a/package-lock.json b/package-lock.json index 613c25ef0..a8b8a5930 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@sinclair/typebox", - "version": "0.31.21", + "version": "0.31.22", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@sinclair/typebox", - "version": "0.31.21", + "version": "0.31.22", "license": "MIT", "devDependencies": { "@sinclair/hammer": "^0.18.0", diff --git a/package.json b/package.json index 0b8deb405..2cb992096 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sinclair/typebox", - "version": "0.31.21", + "version": "0.31.22", "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript", "keywords": [ "typescript", diff --git a/src/typebox.ts b/src/typebox.ts index 0f9d2e03c..e105237f6 100644 --- a/src/typebox.ts +++ b/src/typebox.ts @@ -650,7 +650,7 @@ export interface TPromise extends TSchema { export type TRecordFromUnionLiteralString = { [_ in K['const']]: T } export type TRecordFromUnionLiteralNumber = { [_ in K['const']]: T } // prettier-ignore -export type TRecordFromEnumKey = Ensure> +export type TRecordFromEnumKey, T extends TSchema> = Ensure> // prettier-ignore export type TRecordFromUnionRest = K extends [infer L, ...infer R] ? ( L extends TUnion ? TRecordFromUnionRest & TRecordFromUnionRest, T> : @@ -671,7 +671,7 @@ export type TRecordFromNumberKey = Ensure< export type TRecordFromIntegerKey = Ensure> // prettier-ignore export type TRecordResolve = - K extends TEnum ? TRecordFromEnumKey : // Enum before Union (intercept Hint) + K extends TEnum ? TRecordFromEnumKey : // Enum before Union (intercept Hint) K extends TUnion ? TRecordFromUnion : K extends TTemplateLiteral ? TRecordFromTemplateLiteralKey : K extends TLiteralString ? TRecordFromLiteralStringKey : @@ -2915,6 +2915,7 @@ export class JsonTypeBuilder extends TypeBuilder { } /** `[Json]` Creates a Enum type */ public Enum>(item: T, options: SchemaOptions = {}): TEnum { + if (ValueGuard.IsUndefined(item)) return this.Throw('Enum undefined or empty') // prettier-ignore const values1 = Object.getOwnPropertyNames(item).filter((key) => isNaN(key as any)).map((key) => item[key]) as T[keyof T][] const values2 = [...new Set(values1)] diff --git a/test/static/record.ts b/test/static/record.ts index 1951bd4cd..e21356595 100644 --- a/test/static/record.ts +++ b/test/static/record.ts @@ -128,3 +128,51 @@ import { Type, Static } from '@sinclair/typebox' const I = Type.Intersect([R, T]) Expect(I).ToStatic & { x: number; y: number }>() } +{ + // expect T as Object + enum E { + A, + B, + C, + } + const T = Type.Record(Type.Enum(E), Type.Number()) + Expect(T).ToStatic<{ + 0: number + 1: number + 2: number + }> +} +{ + // expect T as Partial Object + enum E { + A, + B, + C, + } + const T = Type.Partial(Type.Record(Type.Enum(E), Type.Number())) + Expect(T).ToStatic<{ + 0?: number + 1?: number + 2?: number + }> +} +{ + // expect T to support named properties + enum E { + A = 'A', + B = 'B', + C = 'C', + } + const T = Type.Record(Type.Enum(E), Type.Number()) + Expect(T).ToStatic<{ + A: number + B: number + C: number + }> +} +{ + // expect T to support named properties + enum E {} + const T = Type.Record(Type.Enum(E), Type.Number()) + Expect(T).ToStatic<{}> +}