如何在使用 Yup 不允许类型强制的同时允许字段未定义?
How do I allow a field to be undefined while disallowing type coercion using Yup?
我正在尝试使用 yup 验证对象的字段。
这些是我的要求:
- 该字段应为字符串或未定义。
- 如果未定义,应该给它一个默认值。
- 如果它是其他类型的值,则不应将其强制转换为字符串。相反,它应该是不兼容的并且会导致错误。
到目前为止我已经尝试了以下方法:
一个。以下模式不会阻止类型强制。例如当值为数字时,它通过验证。但是,我希望它无法通过验证。
const schema = yup.object().shape({
myField: yup.string().default('myDefaultString')
});
乙。以下架构可防止类型强制转换,但当我传递未定义的值时它会失败。如果给出未定义的值,我实际上希望该值为 'myDefaultString'。
const schema = yup.object().shape({
myField: yup.string().strict(true).default('myDefaultString')
});
C。以下架构与选项 B 具有相同的结果。
const schema = yup.object().shape({
myField: yup.string().strict(true).notRequired().default('myDefaultString')
});
D.在使用 validateSync
方法验证架构时,使用 strict: true
作为选项的一部分。同样,这与 B.
具有相同的结果
非常感谢对此的任何帮助,谢谢!
我认为您可以按如下方式扩展 yup 字符串:
class StrictString extends yup.string {
constructor() {
super();
transforms = []; // remove the default type coercion transforms
}
}
然后,将 StrictString()
替换为 yup.string()
。
这将符合要求。
Yup 能够使用 yup.lazy
* 满足您的所有三个要求,它在 validation/cast 时间创建一个模式。它的可读性也很高,因为它使用了易于理解的 switch
语句。
下面根据你的条件评估一个值:
const StringOrUndefinedSchema = yup.lazy((value) => {
switch (typeof value) {
case 'undefined':
return yup.string().default('myDefaultString');
case 'string':
return yup.string().strict();
default:
throw new yup.ValidationError("Value must be a string or `undefined`");
}
});
然后它可以在任何地方使用,包括您示例中的对象字段:
const ObjectWithFieldSchema = yup.object({
myField: StringOrUndefinedSchema,
});
综合起来:
const yup = require("yup");
const StringOrUndefinedSchema = yup.lazy((value) => {
switch (typeof value) {
case 'undefined':
return yup.string().default('myDefaultString');
case 'string':
return yup.string();
default:
throw new yup.ValidationError("Value must be a string or `undefined`");
}
});
const ObjectWithFieldSchema = yup.object({
myField: StringOrUndefinedSchema,
});
const iWillDefault = await ObjectWithFieldSchema.validate({ });
const iWillBeStrict = await ObjectWithFieldSchema.validate({ myField: "I am a string" });
console.log(iWillDefault); // { myField: "myDefaultString" }
console.log(iWillBeStrict); // { myField: "I am a string" }
在此处查看之前关于 RunKit 的示例代码:https://runkit.com/joematune/6138658a9113f00008292564
我正在尝试使用 yup 验证对象的字段。
这些是我的要求:
- 该字段应为字符串或未定义。
- 如果未定义,应该给它一个默认值。
- 如果它是其他类型的值,则不应将其强制转换为字符串。相反,它应该是不兼容的并且会导致错误。
到目前为止我已经尝试了以下方法:
一个。以下模式不会阻止类型强制。例如当值为数字时,它通过验证。但是,我希望它无法通过验证。
const schema = yup.object().shape({
myField: yup.string().default('myDefaultString')
});
乙。以下架构可防止类型强制转换,但当我传递未定义的值时它会失败。如果给出未定义的值,我实际上希望该值为 'myDefaultString'。
const schema = yup.object().shape({
myField: yup.string().strict(true).default('myDefaultString')
});
C。以下架构与选项 B 具有相同的结果。
const schema = yup.object().shape({
myField: yup.string().strict(true).notRequired().default('myDefaultString')
});
D.在使用 validateSync
方法验证架构时,使用 strict: true
作为选项的一部分。同样,这与 B.
非常感谢对此的任何帮助,谢谢!
我认为您可以按如下方式扩展 yup 字符串:
class StrictString extends yup.string {
constructor() {
super();
transforms = []; // remove the default type coercion transforms
}
}
然后,将 StrictString()
替换为 yup.string()
。
这将符合要求。
Yup 能够使用 yup.lazy
* 满足您的所有三个要求,它在 validation/cast 时间创建一个模式。它的可读性也很高,因为它使用了易于理解的 switch
语句。
下面根据你的条件评估一个值:
const StringOrUndefinedSchema = yup.lazy((value) => {
switch (typeof value) {
case 'undefined':
return yup.string().default('myDefaultString');
case 'string':
return yup.string().strict();
default:
throw new yup.ValidationError("Value must be a string or `undefined`");
}
});
然后它可以在任何地方使用,包括您示例中的对象字段:
const ObjectWithFieldSchema = yup.object({
myField: StringOrUndefinedSchema,
});
综合起来:
const yup = require("yup");
const StringOrUndefinedSchema = yup.lazy((value) => {
switch (typeof value) {
case 'undefined':
return yup.string().default('myDefaultString');
case 'string':
return yup.string();
default:
throw new yup.ValidationError("Value must be a string or `undefined`");
}
});
const ObjectWithFieldSchema = yup.object({
myField: StringOrUndefinedSchema,
});
const iWillDefault = await ObjectWithFieldSchema.validate({ });
const iWillBeStrict = await ObjectWithFieldSchema.validate({ myField: "I am a string" });
console.log(iWillDefault); // { myField: "myDefaultString" }
console.log(iWillBeStrict); // { myField: "I am a string" }
在此处查看之前关于 RunKit 的示例代码:https://runkit.com/joematune/6138658a9113f00008292564