Adding 'required_error' and 'invalid_type_error' properties to already created ZodTypes

huangapple go评论57阅读模式
英文:

Adding 'required_error' and 'invalid_type_error' properties to already created ZodTypes

问题

I understand your request. Here's the translated code part:

我想要输入一个具有类似于 z.stringz.numberz.boolean 和任何 zodtypes 的对象然后在返回时我希望返回相同的对象但是 ZodTypes 将添加 required_error  invalid_type_error 属性
所以想法是像这样输入对象

const myInputObject = { age: z.number(), name: z.string() }

然后在使用该函数时,如下所示:

const myOutputObject = addRequiredAndInvalidErrors(myObject);

'myOutputObject' 将是一个可以像这样正常创建的对象:

const myOutputObject = { age: z.number({ required_error: "Age is required", invalid_type_error: "Age must be a number" }),
name: z.string({ required_error: "Name is required", invalid_type_error: "Name must be a string" }) };

目前我有这个函数:

export const addRequiredAndInvalidErrors = <T extends Record<string, ZodTypeAny>>(schemaObject: T) => {
for (const [field, type] of Object.entries(schemaObject)) {
const required_error = ${titleWords(field)} is required;
const invalid_type_error = ${titleWords(field)} must be a ${schemaObject[field]._def.typeName.split("Zod")[1]};
console.log(field, type._def);
}
return schemaObject;
};

function titleWords(myStr: string) {
return myStr.replace(/(^\w{1})|(\s+\w{1})/g, letter => letter.toUpperCase());
}


唯一缺失的部分是将 required_error 和 invalid_type_error 分配给每个变量,我已经获取了对象的每个变量的正确值。

**编辑 1:**
我注意到当我像这样直接放置 required_error 和 invalid_type_error 时:

const myObject = { age: z.number({ required_error: "Age is required", invalid_type_error: "Age must be a number" }), name: z.string() };

并像这样在控制台中打印 type._def:

console.log(field, type._def);

我得到:

age {
checks: [],
typeName: 'ZodNumber',
coerce: false,
errorMap: [Function: customMap],
description: undefined
}
name { checks: [], typeName: 'ZodString', coerce: false }

所以,当你有 required_error 和/或 invalid_type_error 时,它会在 '_def' 中创建一个 'errorMap'。

希望这有所帮助。
英文:

I want to input an object with ZodTypes like z.string, z.number, z.boolean, any zodtypes, and when returning I want to return the same object but the ZodTypes will have added properties required_error and invalid_type_error.
So the idea is to have an object like this as input or something like it:

const myInputObject = { age: z.number(), name: z.string() }

and then when using the function like this:

const myOutputObject = addRequiredAndInvalidErrors(myObject);

the 'myOutputObject' would be an object that could be created normally like this:

const myOutputObject = { age: z.number({ required_error: &quot;Age is required&quot;, invalid_type_error: &quot;Age must be a number&quot; }),
	name: z.string({ required_error: &quot;Name is required&quot;, invalid_type_error: &quot;Name must be a string&quot; }) };

Currently I have this as function:

export const addRequiredAndInvalidErrors = &lt;T extends Record&lt;string, ZodTypeAny&gt;&gt;(schemaObject: T) =&gt; {
	for (const [field,type] of Object.entries(schemaObject)) {
		const required_error = `${titleWords(field)} is required`;
		const invalid_type_error = `${titleWords(field)} must be a ${schemaObject[field]._def.typeName.split(&quot;Zod&quot;)[1]}`;
		console.log(field, type._def);
	}
	return schemaObject;
};


function titleWords (myStr: string) {
	return myStr.replace(/(^\w{1})|(\s+\w{1})/g, letter =&gt; letter.toUpperCase());
}

The only part that is missing is to attribute the required_error and invalid_type_error to each variable, I am already getting the correct values for each variable of the object.

Edit 1:
What I've noticed is when I put the required_error and invalid_type_error directly like this:

const myObject = { age: z.number({ required_error: &quot;Age is required&quot;, invalid_type_error: &quot;Age must be a number&quot; }), name: z.string() };

and console.log the type._def like this

		console.log(field, type._def);

I get:

age {
  checks: [],
  typeName: &#39;ZodNumber&#39;,
  coerce: false,
  errorMap: [Function: customMap],
  description: undefined
}
name { checks: [], typeName: &#39;ZodString&#39;, coerce: false }

So when you have the required_error and/or the invalid_type_error, it creates an 'errorMap' in the '_def'.

Hope this helps in a way.

答案1

得分: 1

以下是代码部分的翻译:

export const addRequiredAndInvalidErrors = <T extends ZodTypeAny>(field: string, schema: T): T => {
  const required_error = `${titleWords(field)} is required`;
  const invalid_type_error = `${titleWords(field)} must be a ${schema._def.typeName.split('Zod')[1]}`;
  const originErrorMap = schema._def.errorMap;
  schema._def.errorMap = (iss, ctx) => {
    if (originErrorMap) {
      const originError = originErrorMap(iss, ctx);
      if (originError.message !== ctx.defaultError) {
        return originError;
      }
    }
    if (typeof ctx.data === 'undefined') {
      return {message: required_error ?? ctx.defaultError};
    }
    return {message: invalid_type_error ?? ctx.defaultError};
  };
  return schema;
};

function titleWords(myStr: string) {
  return myStr.replace(/(^\w{1})|(\s+\w{1})/g, letter => letter.toUpperCase());
}

export const myOutputObject = addRequiredAndInvalidErrors('name', z.string());

console.log(myOutputObject.safeParse(undefined));
// console: Name is required

console.log(myOutputObject.safeParse({}));
// console: Name must be a String

如果您有任何其他需要翻译的内容,请随时提出。

英文:

You need manually change the errorMap. Here give a sample to change one schema. You can extend it for your Record

export const addRequiredAndInvalidErrors = &lt;T extends ZodTypeAny&gt;(field: string, schema: T): T =&gt; {
  const required_error = `${titleWords(field)} is required`;
  const invalid_type_error = `${titleWords(field)} must be a ${schema._def.typeName.split(&#39;Zod&#39;)[1]}`;
  const originErrorMap = schema._def.errorMap;
  schema._def.errorMap = (iss, ctx) =&gt; {
    if (originErrorMap) {
      const originError = originErrorMap(iss, ctx);
      if (originError.message !== ctx.defaultError) {
        return originError;
      }
    }
    if (typeof ctx.data === &#39;undefined&#39;) {
      return {message: required_error ?? ctx.defaultError};
    }
    return {message: invalid_type_error ?? ctx.defaultError};
  };
  return schema;
};


function titleWords(myStr: string) {
  return myStr.replace(/(^\w{1})|(\s+\w{1})/g, letter =&gt; letter.toUpperCase());
}

export const myOutputObject = addRequiredAndInvalidErrors(&#39;name&#39;, z.string());


console.log(myOutputObject.safeParse(undefined));
// console: Name is required

console.log(myOutputObject.safeParse({}));
/ /console: Name must be a String

huangapple
  • 本文由 发表于 2023年5月25日 03:46:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76326936.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定