javascript - Hur tillåter jag att ett fält är odefinierat samtidigt som jag förhindrar typkonvertering med Yup?
Jag försöker validera ett objekts fält med yup.
Det här är mina krav:
- Fältet ska antingen vara en sträng eller odefinierat.
- Om det är odefinierat bör det få ett standardvärde.
- Om det är ett värde av någon annan typ bör det inte tvingas till en sträng. Istället bör det vara inkompatibelt och resultera i ett fel.
Jag har försökt följande hittills:
A. Följande schema förhindrar inte typkonvertering. t.ex. när värdet är ett nummer, klarar det valideringen. Jag vill dock att det ska misslyckas med valideringen.
const schema = yup.object().shape({
myField: yup.string().default('myDefaultString')
});
B. Följande schema förhindrar typkonvertering, men det misslyckas när jag skickar ett undefined-värde. Jag vill faktiskt att värdet ska vara 'myDefaultString' om ett undefined-värde anges.
const schema = yup.object().shape({
myField: yup.string().strict(true).default('myDefaultString')
});
C. Följande schema har samma resultat som alternativ B.
const schema = yup.object().shape({
myField: yup.string().strict(true).notRequired().default('myDefaultString')
});
D. Använd strict: true som en del av alternativen när du använder validateSync-metoden för att validera schemat. Återigen har detta samma resultat som B.
Skulle uppskatta all hjälp med detta, tack!
Svar #1
Yup kan uppfylla alla tre dina krav med yup.lazy* som skapar ett schema vid validering/kastningstid. Det är också mycket läsbart eftersom det använder ett lättföljt switch-uttalande.
Följande utvärderar ett värde baserat på dina villkor:
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`");
}
});
Det kan då användas var som helst, inklusive ett objekts fält som i ditt exempel:
const ObjectWithFieldSchema = yup.object({
myField: StringOrUndefinedSchema,
});
Sammanfatta allt:
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" }
Visa det tidigare exempel på koden på RunKit här: https://runkit.com/joematune/6138658a9113f00008292564
- Yup.lazy - https://github.com/jquense/yup#yuplazyvalue-any--schema-lazy
Svar #2
Jag tänkte att du kan förlänga yup-strängen på följande sätt:
class StrictString extends yup.string {
constructor() {
super();
transforms = []; // remove the default type coercion transforms
}
}
Och sedan, ersätt StrictString() med yup.string(). Detta kommer att passa kraven.
