I'm trying to validate an object's field using yup.
These are my requirements:
- The field should either be a string or undefined.
- If it is undefined, it should be given a default value.
- If it is a value of some other type, it should not be coerced into a string. Instead, it should be inpatible and should result in an error.
I've tried the following so far:
A. The following schema does not prevent type coercion. e.g. when the value is a number, it passes the validation. However, I want it to fail the validation.
const schema = yup.object().shape({
myField: yup.string().default('myDefaultString')
});
B. The following schema prevents type coercion, but it fails when I pass an undefined value. I actually want the value to be 'myDefaultString' if an undefined value is given.
const schema = yup.object().shape({
myField: yup.string().strict(true).default('myDefaultString')
});
C. The following schema has the same result as option B.
const schema = yup.object().shape({
myField: yup.string().strict(true).notRequired().default('myDefaultString')
});
D. Use strict: true
as part of the options when using validateSync
method to validate the schema. Again, this has the same result as B.
Would appreciate any help with this, thanks!
I'm trying to validate an object's field using yup.
These are my requirements:
- The field should either be a string or undefined.
- If it is undefined, it should be given a default value.
- If it is a value of some other type, it should not be coerced into a string. Instead, it should be inpatible and should result in an error.
I've tried the following so far:
A. The following schema does not prevent type coercion. e.g. when the value is a number, it passes the validation. However, I want it to fail the validation.
const schema = yup.object().shape({
myField: yup.string().default('myDefaultString')
});
B. The following schema prevents type coercion, but it fails when I pass an undefined value. I actually want the value to be 'myDefaultString' if an undefined value is given.
const schema = yup.object().shape({
myField: yup.string().strict(true).default('myDefaultString')
});
C. The following schema has the same result as option B.
const schema = yup.object().shape({
myField: yup.string().strict(true).notRequired().default('myDefaultString')
});
D. Use strict: true
as part of the options when using validateSync
method to validate the schema. Again, this has the same result as B.
Would appreciate any help with this, thanks!
Share Improve this question edited Jun 18, 2020 at 8:37 Teik Jun asked Jun 18, 2020 at 8:21 Teik JunTeik Jun 3912 gold badges3 silver badges12 bronze badges2 Answers
Reset to default 3Yup is capable of satisfying all three of your requirements using yup.lazy
* which creates a schema at validation/cast time. It's also highly readable as it utilizes an easy to follow switch
statement.
The following evaluates a value based on your conditions:
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`");
}
});
It can then be used anywhere, including an object's field as in your example:
const ObjectWithFieldSchema = yup.object({
myField: StringOrUndefinedSchema,
});
Putting it all together:
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" }
View the previous example code on RunKit here: https://runkit./joematune/6138658a9113f00008292564
- Yup.lazy - https://github./jquense/yup#yuplazyvalue-any--schema-lazy
I figured that you can extend the yup string as follows:
class StrictString extends yup.string {
constructor() {
super();
transforms = []; // remove the default type coercion transforms
}
}
And then, replace StrictString()
with yup.string()
.
This will fit the requirements.