@@ -1314,14 +1314,65 @@ export function zBrand<
13141314/** Simple type conversion from a Convex validator to a Zod validator. */
13151315export type ConvexToZod < V extends GenericValidator > = z . ZodType < Infer < V > > ;
13161316
1317+ /** Better type conversion from a Convex validator to a Zod validator where the output is not a generetic ZodType but it's more specific.
1318+ *
1319+ * ES: z.ZodString instead of z.ZodType<string, z.ZodTypeDef, string>
1320+ * so you can use methods of z.ZodString like .min() or .email()
1321+ */
1322+
1323+ type ZodFromValidatorBase < V extends GenericValidator > =
1324+ V extends VId < GenericId < infer TableName extends string > >
1325+ ? Zid < TableName >
1326+ : V extends VString < any , any >
1327+ ? z . ZodString
1328+ : V extends VFloat64 < any , any >
1329+ ? z . ZodNumber
1330+ : V extends VInt64 < any , any >
1331+ ? z . ZodBigInt
1332+ : V extends VBoolean < any , any >
1333+ ? z . ZodBoolean
1334+ : V extends VNull < any , any >
1335+ ? z . ZodNull
1336+ : V extends VLiteral < any , any >
1337+ ? z . ZodLiteral < V [ "value" ] >
1338+ : V extends VObject < any , any , any , any >
1339+ ? z . ZodObject < {
1340+ [ K in keyof V [ "fields" ] ] : ZodValidatorFromConvex <
1341+ V [ "fields" ] [ K ]
1342+ > ;
1343+ } >
1344+ : V extends VRecord < any , infer Key , any , any , any >
1345+ ? Key extends VId < GenericId < infer TableName > >
1346+ ? z . ZodRecord <
1347+ Zid < TableName > ,
1348+ ZodValidatorFromConvex < V [ "value" ] >
1349+ >
1350+ : z . ZodRecord <
1351+ z . ZodString ,
1352+ ZodValidatorFromConvex < V [ "value" ] >
1353+ >
1354+ : V extends VArray < any , any >
1355+ ? z . ZodArray < ZodValidatorFromConvex < V [ "element" ] > >
1356+ : V extends VUnion < any , any , any , any >
1357+ ? z . ZodUnion <
1358+ [ ZodValidatorFromConvex < V [ "members" ] [ number ] > ]
1359+ >
1360+ : z . ZodTypeAny ; // fallback for unknown validators
1361+
1362+ /** Main type with optional handling. */
1363+ export type ZodValidatorFromConvex < V extends GenericValidator > =
1364+ V extends Validator < any , "optional" , any >
1365+ ? z . ZodOptional < ZodFromValidatorBase < V > >
1366+ : ZodFromValidatorBase < V > ;
1367+
13171368/**
13181369 * Turn a Convex validator into a Zod validator.
13191370 * @param convexValidator Convex validator can be any validator from "convex/values" e.g. `v.string()`
13201371 * @returns Zod validator (e.g. `z.string()`) with inferred type matching the Convex validator
13211372 */
13221373export function convexToZod < V extends GenericValidator > (
13231374 convexValidator : V ,
1324- ) : z . ZodType < Infer < V > > {
1375+ ) : ZodValidatorFromConvex < V > {
13251376 const isOptional = ( convexValidator as any ) . isOptional === "optional" ;
13261377
13271378 let zodValidator : z . ZodTypeAny ;
@@ -1393,7 +1444,9 @@ export function convexToZod<V extends GenericValidator>(
13931444 throw new Error ( `Unknown convex validator type: ${ convexValidator . kind } ` ) ;
13941445 }
13951446
1396- return isOptional ? z . optional ( zodValidator ) : zodValidator ;
1447+ return isOptional
1448+ ? ( z . optional ( zodValidator ) as ZodValidatorFromConvex < V > )
1449+ : ( zodValidator as ZodValidatorFromConvex < V > ) ;
13971450}
13981451
13991452/**
@@ -1408,5 +1461,5 @@ export function convexToZodFields<C extends PropertyValidators>(
14081461) {
14091462 return Object . fromEntries (
14101463 Object . entries ( convexValidators ) . map ( ( [ k , v ] ) => [ k , convexToZod ( v ) ] ) ,
1411- ) as { [ k in keyof C ] : z . ZodType < Infer < C [ k ] > > } ;
1464+ ) as { [ k in keyof C ] : ZodValidatorFromConvex < C [ k ] > } ;
14121465}
0 commit comments