typescript error when flattenting a zoderror object

function flattenError(error: ZodError<z.ZodObject>) {
const treefiedError = z.treeifyError(error);

if (treefiedError.properties !== undefined) {
const properties = treefiedError.properties;
const flattenedError : Record<string, string> = {};

for (const property in properties) {
flattenedError[property] = properties[property]
}
}
}
function flattenError(error: ZodError<z.ZodObject>) {
const treefiedError = z.treeifyError(error);

if (treefiedError.properties !== undefined) {
const properties = treefiedError.properties;
const flattenedError : Record<string, string> = {};

for (const property in properties) {
flattenedError[property] = properties[property]
}
}
}
I have this code here. the error parameter after being passed to treeifyError would output value like this
{
"errors": [],
"properties": {
"name": {
"errors": [
"name must be at least 4 characters long",
],
},
"password": {
"errors": [
"password must be at least 8 characters long",
],
},
"passwordConfirm": {
"errors": [
"Too small: expected string to have >8 characters",
],
},
},
}
{
"errors": [],
"properties": {
"name": {
"errors": [
"name must be at least 4 characters long",
],
},
"password": {
"errors": [
"password must be at least 8 characters long",
],
},
"passwordConfirm": {
"errors": [
"Too small: expected string to have >8 characters",
],
},
},
}
I wanted to flatten it into something like this
{"password" : "password must be at least 8 characters long",
"name" : "name must be at least 8 characters long"}
{"password" : "password must be at least 8 characters long",
"name" : "name must be at least 8 characters long"}
but the typescript keeps complaining here and outputs a deeply nested type. Is there a way to make this easier to flatten?
No description
1 Reply
Ganesh
GaneshOP3mo ago
by the way I did try flattenError method of zod but typescript marks it as deprecated
export type $ZodErrorTree<T, U = string> = T extends [any, ...any[]] ? {
errors: U[];
items?: {
[K in keyof T]?: $ZodErrorTree<T[K], U>;
};
} : T extends any[] ? {
errors: U[];
items?: Array<$ZodErrorTree<T[number], U>>;
} : T extends object ? {
errors: U[];
properties?: {
[K in keyof T]?: $ZodErrorTree<T[K], U>;
};
} : {
errors: U[];
};
export type $ZodErrorTree<T, U = string> = T extends [any, ...any[]] ? {
errors: U[];
items?: {
[K in keyof T]?: $ZodErrorTree<T[K], U>;
};
} : T extends any[] ? {
errors: U[];
items?: Array<$ZodErrorTree<T[number], U>>;
} : T extends object ? {
errors: U[];
properties?: {
[K in keyof T]?: $ZodErrorTree<T[K], U>;
};
} : {
errors: U[];
};
I think this is the return type of treeifyError method is working with typescript always this complex or this is easy and I just don't know enough Honestly this ternary operator usage is disgusting
function flattenError(error: ZodError<object>) {
const treefiedError = z.treeifyError(error);

if (treefiedError.properties !== undefined) {
//assert properties type otherwise typescript will complain
const properties = treefiedError.properties as Record<
string,
{ errors: string[] }
>;
const flattenedError: Record<string, string> = {};

for (const property in properties) {
const errorMessages = properties[property]?.errors;
if (errorMessages && errorMessages.length > 0) {
flattenedError[property] = errorMessages[0];
}
}

return flattenedError;
} else {
return {};
}
}
function flattenError(error: ZodError<object>) {
const treefiedError = z.treeifyError(error);

if (treefiedError.properties !== undefined) {
//assert properties type otherwise typescript will complain
const properties = treefiedError.properties as Record<
string,
{ errors: string[] }
>;
const flattenedError: Record<string, string> = {};

for (const property in properties) {
const errorMessages = properties[property]?.errors;
if (errorMessages && errorMessages.length > 0) {
flattenedError[property] = errorMessages[0];
}
}

return flattenedError;
} else {
return {};
}
}
this sorta works but i had to use assertation and object type

Did you find this page helpful?