Skip to content

Instantly share code, notes, and snippets.

@JacobWeisenburger
Last active January 3, 2023 16:28
Show Gist options
  • Save JacobWeisenburger/d5dbb4d5bcbb287b7661061a78536423 to your computer and use it in GitHub Desktop.
Save JacobWeisenburger/d5dbb4d5bcbb287b7661061a78536423 to your computer and use it in GitHub Desktop.
import { z } from 'zod'
import { mapValues, omit, pick } from 'lodash'
function partialSafeParse<Schema extends z.ZodObject<any>> ( schema: Schema, input: unknown ) {
const result = schema.safeParse( input )
if ( result.success ) return result
const { fieldErrors, formErrors } = result.error.flatten()
if ( formErrors.length ) return result
const inputObj = input as z.infer<Schema>
const keysWithInvalidData = Object.keys( fieldErrors )
const validInput = omit( inputObj, keysWithInvalidData )
const invalidData = pick( inputObj, keysWithInvalidData )
const validData = schema
.omit( mapValues( fieldErrors, () => true as const ) )
.parse( validInput )
return {
success: 'partial',
validData,
invalidData,
fieldErrors,
}
}
const userSchema = z.object( { name: z.string(), age: z.number() } )
console.log( partialSafeParse( userSchema, { name: 'foo', age: 42 } ) )
// { success: true, data: { name: "foo", age: 42 } }
console.log( partialSafeParse( userSchema, { name: null, age: 42 } ) )
// {
// success: "partial",
// validData: { age: 42 },
// invalidData: { name: null },
// fieldErrors: { name: [ "Expected string, received null" ] }
// }
console.log( partialSafeParse( userSchema, { name: null } ) )
// {
// success: "partial",
// validData: {},
// invalidData: { name: null },
// fieldErrors: { name: [ "Expected string, received null" ], age: [ "Required" ] }
// }
console.log( partialSafeParse( userSchema, {} ) )
// {
// success: "partial",
// validData: {},
// invalidData: {},
// fieldErrors: { name: [ "Required" ], age: [ "Required" ] }
// }
console.log( partialSafeParse( userSchema, null ) )
// {
// success: false,
// error: ZodError: [
// {
// "code": "invalid_type",
// "expected": "object",
// "received": "null",
// "path": [],
// "message": "Expected object, received null"
// }
// ]
// at handleResult (https://deno.land/x/zod@v3.20.2/types.ts:94:19)
// at ZodObject.safeParse (https://deno.land/x/zod@v3.20.2/types.ts:231:12)
// at partialSafeParse (file:///C:/_Software/deno-sandbox/zod/mod.ts:16:27)
// at file:///C:/_Software/deno-sandbox/zod/mod.ts:44:14
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment