Is there a z.ZodSchema specifically for objects? #874
-
I have a typescript object type and want to create a zod schema from it. type Obj = {
a: 'a';
}
const Schema: z.ZodSchema<Obj> = z.object({
a: z.literal('a'),
}) But this schema is not a zod object schema. This means I can't do this: const NewSchema = Schema.extends({
b: z.string(),
}) ... extends is undefined. Is there any inbuilt solution to this issue? This seems to work in some cases but it fails in others like the react-hook-form resolver. type ZodObjectSchema<
T extends AnyObject,
TK extends { [K in keyof T]: z.ZodType<T[K]> } = { [K in keyof T]: z.ZodType<T[K]> }
> = z.ZodObject<
TK,
'strip',
z.ZodTypeAny,
{
[k_1 in keyof z.objectUtil.addQuestionMarks<{
[k in keyof TK]: TK[k]['_output'];
}>]: z.objectUtil.addQuestionMarks<{
[k in keyof TK]: TK[k]['_output'];
}>[k_1];
},
{
[k_3 in keyof z.objectUtil.addQuestionMarks<{
[k_2 in keyof TK]: TK[k_2]['_input'];
}>]: z.objectUtil.addQuestionMarks<{
[k_2 in keyof TK]: TK[k_2]['_input'];
}>[k_3];
}
>;
type ObjA = {
a: 'a';
};
type ObjB = {
b: 'b';
};
type Combined = ObjA & ObjB;
const CombinedSchema: ZodObjectSchema<Combined> = z.object({
a: z.literal('a'),
b: z.literal('b'),
});
const BSchema = CombinedSchema.omit({ a: true });
type InferredB = z.infer<typeof BSchema>;
type Works = InferredB extends ObjB ? true : false;
const works: Works = true;
/// Whereas
const CombinedSchemaInbuilt: z.ZodSchema<Combined> = z.object({
a: z.literal('a'),
b: z.literal('b'),
});
// CombinedSchemaInbuild.omit
// Property 'omit' does not exist on type 'ZodType<Combined, ZodTypeDef, Combined>'.ts(2339) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
I don't think there is. I'm pretty sure you are looking for something like type ShapeFromData<Data extends Record<string, any> | undefined> = Data extends undefined ? never : {
[ key in keyof Data ]-?:
unknown extends Data[ key ] ? z.ZodType<Data[ key ]> | z.ZodOptional<z.ZodType<Data[ key ]>> :
undefined extends Data[ key ] ? z.ZodOptional<z.ZodType<Data[ key ]>> :
z.ZodType<Data[ key ]>
} type Obj = {
a: 'a'
}
const schema = z.object<ShapeFromData<Obj>>( {
a: z.literal( 'a' ),
} )
type Schema = z.infer<typeof schema>
//-> Schema = {
// a: "a";
// }
const newSchema = schema.extend( {
b: z.string(),
} )
type NewSchema = z.infer<typeof newSchema>
//-> NewSchema = {
// a: "a";
// b: string;
// } |
Beta Was this translation helpful? Give feedback.
I don't think there is.
I'm pretty sure you are looking for something like
ShapeFromData
(see below). I modified this from a few other implementations that I found online. So far it has been working well for me, but I haven't tested it for every possible schema. Let me know what you think?