File tree Expand file tree Collapse file tree 4 files changed +35
-14
lines changed
Expand file tree Collapse file tree 4 files changed +35
-14
lines changed Original file line number Diff line number Diff line change @@ -639,15 +639,35 @@ describe("toJSONSchema", () => {
639639
640640 // enum
641641 test ( "enum" , ( ) => {
642- const schema = z . enum ( [ "a" , "b" , "c" ] ) ;
643- expect ( z . toJSONSchema ( schema ) ) . toMatchInlineSnapshot ( `
642+ const a = z . enum ( [ "a" , "b" , "c" ] ) ;
643+ expect ( z . toJSONSchema ( a ) ) . toMatchInlineSnapshot ( `
644644 {
645645 "$schema": "https://json-schema.org/draft/2020-12/schema",
646646 "enum": [
647647 "a",
648648 "b",
649649 "c",
650650 ],
651+ "type": "string",
652+ }
653+ ` ) ;
654+
655+ enum B {
656+ A = 0 ,
657+ B = 1 ,
658+ C = 2 ,
659+ }
660+
661+ const b = z . enum ( B ) ;
662+ expect ( z . toJSONSchema ( b ) ) . toMatchInlineSnapshot ( `
663+ {
664+ "$schema": "https://json-schema.org/draft/2020-12/schema",
665+ "enum": [
666+ 0,
667+ 1,
668+ 2,
669+ ],
670+ "type": "number",
651671 }
652672 ` ) ;
653673 } ) ;
Original file line number Diff line number Diff line change @@ -2636,10 +2636,7 @@ export interface $ZodEnum<T extends util.EnumLike = util.EnumLike> extends $ZodT
26362636export const $ZodEnum : core . $constructor < $ZodEnum > = /*@__PURE__ */ core . $constructor ( "$ZodEnum" , ( inst , def ) => {
26372637 $ZodType . init ( inst , def ) ;
26382638
2639- const numericValues = Object . values ( def . entries ) . filter ( ( v ) => typeof v === "number" ) ;
2640- const values = Object . entries ( def . entries )
2641- . filter ( ( [ k , _ ] ) => numericValues . indexOf ( + k ) === - 1 )
2642- . map ( ( [ _ , v ] ) => v ) ;
2639+ const values = util . getEnumValues ( def . entries ) ;
26432640
26442641 inst . _zod . values = new Set < util . Primitive > ( values ) ;
26452642
Original file line number Diff line number Diff line change @@ -2,6 +2,7 @@ import type * as checks from "./checks.js";
22import type * as JSONSchema from "./json-schema.js" ;
33import { $ZodRegistry , globalRegistry } from "./registries.js" ;
44import type * as schemas from "./schemas.js" ;
5+ import { getEnumValues } from "./util.js" ;
56
67interface JSONSchemaGeneratorParams {
78 /** A registry used to look up metadata for each schema. Any schema with an `id` property will be extracted as a $def.
@@ -400,7 +401,11 @@ export class JSONSchemaGenerator {
400401 }
401402 case "enum" : {
402403 const json : JSONSchema . BaseSchema = _json as any ;
403- json . enum = Object . values ( def . entries ) ;
404+ const values = getEnumValues ( def . entries ) ;
405+ // Number enums can have both string and number values
406+ if ( values . every ( ( v ) => typeof v === "number" ) ) json . type = "number" ;
407+ if ( values . every ( ( v ) => typeof v === "string" ) ) json . type = "string" ;
408+ json . enum = values ;
404409 break ;
405410 }
406411 case "literal" : {
Original file line number Diff line number Diff line change @@ -203,13 +203,12 @@ export function assertNever(_x: never): never {
203203}
204204export function assert < T > ( _ : any ) : asserts _ is T { }
205205
206- export function getValidEnumValues ( obj : any ) : any {
207- const validKeys = Object . keys ( obj ) . filter ( ( k : any ) => typeof obj [ obj [ k ] ] !== "number" ) ;
208- const filtered : any = { } ;
209- for ( const k of validKeys ) {
210- filtered [ k ] = obj [ k ] ;
211- }
212- return Object . values ( filtered ) ;
206+ export function getEnumValues ( entries : EnumLike ) : EnumValue [ ] {
207+ const numericValues = Object . values ( entries ) . filter ( ( v ) => typeof v === "number" ) ;
208+ const values = Object . entries ( entries )
209+ . filter ( ( [ k , _ ] ) => numericValues . indexOf ( + k ) === - 1 )
210+ . map ( ( [ _ , v ] ) => v ) ;
211+ return values ;
213212}
214213
215214export function joinValues < T extends Primitive [ ] > ( array : T , separator = "|" ) : string {
You can’t perform that action at this time.
0 commit comments