zod
zod copied to clipboard
feat: Add the anyObject type
Fixes https://github.com/colinhacks/zod/issues/1628 .
This allows the use of z.anyObject()
for validation situations where a property is required to be an object but we don't care to validate its exact shape / properties. Other types are easy to define as indiscriminate versions of themselves, except for objects. And using z.any()
causes the property to be optional (as noticed in https://github.com/colinhacks/zod/issues/1628).
Deploy Preview for guileless-rolypoly-866f8a ready!
Built without sensitive environment variables
Name | Link |
---|---|
Latest commit | e24b16d09769eeae15dc167f29a17877c7024ce7 |
Latest deploy log | https://app.netlify.com/sites/guileless-rolypoly-866f8a/deploys/63b580a1ccac490008720d7f |
Deploy Preview | https://deploy-preview-1675--guileless-rolypoly-866f8a.netlify.app |
Preview on mobile | Toggle QR Code...Use your smartphone camera to open QR code link. |
To edit notification comments on pull requests, go to your Netlify site settings.
Hey guys, what is the status of this one? We started using zod in our company and this is a big issue for us.
I'm not sure that we need z.anyObject
because we have z.record(z.any())
. It seems to work the way that you have described. Is there anything I'm missing?
const anyObjectSchema = z.record( z.any() )
type AnyObject = z.infer<typeof anyObjectSchema>
// type AnyObject = {
// [ x: string ]: any
// }
console.log( anyObjectSchema.safeParse( { a: 1, b: 2 } ).success ) // true
console.log( anyObjectSchema.safeParse( {} ).success ) // true
console.log( anyObjectSchema.safeParse( [] ).success ) // false
console.log( anyObjectSchema.safeParse( 'foo' ).success ) // false
console.log( anyObjectSchema.safeParse( 42 ).success ) // false
console.log( anyObjectSchema.safeParse( null ).success ) // false
console.log( anyObjectSchema.safeParse( undefined ).success ) // false
This PR was made in response to this comment: https://github.com/colinhacks/zod/issues/1628#issuecomment-1338138675
Also, the inferred type from z.record( z.any())
is { [ x: string ]: any }
. This is not exactly the TypeScript object
type (which I've made z.anyObject()
output to), although they would generally be interchangeable.
I also think that since we have z.object()
- having a similarly named z.anyObject()
makes more sense than having to find and understand the ability of z.record( z.any())
to do the same. I've never made use of the z.record()
type, and while it does work for this situation it feels like a bit of a hack rather than a natural type definition for this situation.
There are situations when a type error arises because a type index is expected but not present. I cannot off hand reproduce the situation though. So I'm not sure to what extent @JacobWeisenburger's point stands--about the need or not for a differentiation. I would expect however that a differentiation is needed under advanced cases, type logic, multiple times derived types, etc.
Either of these seem to do what you are asking for. So I'm still not really understanding what z.anyObject()
is supposed to do that other schemas don't.
const emptyObjSchema = z.object( {} )
console.log( emptyObjSchema.safeParse( {} ).success ) // true
console.log( emptyObjSchema.safeParse( { foo: 'foo' } ).success ) // true
console.log( emptyObjSchema.safeParse( [] ).success ) // false
console.log( emptyObjSchema.safeParse( () => { } ).success ) // false
console.log( emptyObjSchema.safeParse( 'foo' ).success ) // false
console.log( emptyObjSchema.safeParse( 42 ).success ) // false
console.log( emptyObjSchema.safeParse( null ).success ) // false
console.log( emptyObjSchema.safeParse( undefined ).success ) // false
const recordSchema = z.record( z.any() )
console.log( recordSchema.safeParse( {} ).success ) // true
console.log( recordSchema.safeParse( { foo: 'foo' } ).success ) // true
console.log( recordSchema.safeParse( [] ).success ) // false
console.log( recordSchema.safeParse( () => { } ).success ) // false
console.log( recordSchema.safeParse( 'foo' ).success ) // false
console.log( recordSchema.safeParse( 42 ).success ) // false
console.log( recordSchema.safeParse( null ).success ) // false
console.log( recordSchema.safeParse( undefined ).success ) // false
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Either of these seem to do what you are asking for. So I'm still not really understanding what
z.anyObject()
is supposed to do that other schemas don't.
Its about the returned type when inferring the type from zod. We still want the type to be object
instead of any
or Record<string, any>
or whatnot. Its not an issue of validation per se- its about how we use zod and TypeScript together to define our interfaces.