基于祖先属性确定Yup模式验证



我希望用yup有效地进行.when('cestor.prop.foo.bar'….(样式验证。我的模式是一个非常大/复杂的数据模型,许多字段的验证都由顶级/嵌套属性控制。

(旁注:使用尾数(

目前,我已经能够用我自己的实现替换mantine的"yupResolver"函数,该实现附加了模式的值以供以后使用:

return (values: Record<string, any>): FormErrors => {
try {
_schema.validateSync(values, { abortEarly: false, fullSchemaValue: values }); // I name it 'fullSchemaValue'
return {};
} catch (_yupError: any) {
const yupError: YupValidationResult = _yupError;
const results: any = {};
yupError.inner.forEach((error: YupError) => {
results[error.path.replaceAll('[', '.').replaceAll(']', '')] = error.message;
});
return results;
}

然后,我在我的模式中制作了一些自定义的yup.test函数:

mySchemaAttribute: yup.string().test('testName1', 'This error message will show', function(value){ // didn't use arrow syntax to preserve 'this'.
const schemaValue: any = (this.options as any)?.fullSchemaValue; // the property I added that holds the schema value exists under 'this.options.[...]'
if(!schemaValue.topLevelObject.otherLayer.mySchemaAttribute && schemaValue.someOtherLocation.otherProp) {
return true
}
return false;
}),

我当然可以制作一套助手函数,并以这种方式处理大多数情况,但这有点粗糙和冗长。有人找到更好的方法吗?

我认为在理想的情况下,我们可以选择性地在实际的yup代码中附加完整的模式值,并对其进行道具钻取,以便在为.when((函数获取密钥的任何操作中使用,但我使用该库的时间还不够长,不知道我是否陷入了一个不成功的兔子洞。

原来自述中的这个小片段是一个银弹:

You can also prefix properties with $ to specify a property that is dependent on context passed in by validate() or cast instead of the input value.

由于我能够给上下文一个值,我可以通过访问它

yup.string().when('$data.topLevelObject.otherLayer.mySchemaAttribute')

需要注意的一点是,您需要将数据本身指定为"context"对象的一部分。

最新更新