javascript - ¿Cómo permito que un campo sea indefinido mientras desactivo la coerción de tipos usando Yup?
Estoy intentando validar el campo de un objeto usando yup.
Estos son mis requisitos:
- El campo debe ser una cadena o indefinido.
- Si está indefinido, se le debe dar un valor por defecto.
- Si es un valor de algún otro tipo, no debe ser convertido en una cadena. En cambio, debe ser incompatible y debería resultar en un error.
He intentado lo siguiente hasta ahora:
A. El siguiente esquema no previene la coerción de tipos. Por ejemplo, cuando el valor es un número, pasa la validación. Sin embargo, quiero que falle la validación.
const schema = yup.object().shape({
myField: yup.string().default('myDefaultString')
});
B. El siguiente esquema previene la coerción de tipos, pero falla cuando paso un valor indefinido. En realidad, quiero que el valor sea 'myDefaultString' si se proporciona un valor indefinido.
const schema = yup.object().shape({
myField: yup.string().strict(true).default('myDefaultString')
});
C. El siguiente esquema tiene el mismo resultado que la opción B.
const schema = yup.object().shape({
myField: yup.string().strict(true).notRequired().default('myDefaultString')
});
D. Use strict: true como parte de las opciones al usar el método validateSync para validar el esquema. Nuevamente, esto tiene el mismo resultado que B.
¡Agradecería cualquier ayuda con esto, gracias!
Respuesta #1
Yup es capaz de satisfacer los tres requisitos utilizando yup.lazy*, que crea un esquema en el momento de la validación/casteo. También es muy legible ya que utiliza una declaración switch fácil de seguir.
Lo siguiente evalúa un valor basado en tus condiciones:
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`");
}
});
Luego puede usarse en cualquier lugar, incluido el campo de un objeto como en tu ejemplo:
const ObjectWithFieldSchema = yup.object({
myField: StringOrUndefinedSchema,
});
Uniéndolo todo:
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" }
Vea el código de ejemplo anterior en RunKit aquí: https://runkit.com/joematune/6138658a9113f00008292564
- Yup.lazy - https://github.com/jquense/yup#yuplazyvalue-any--schema-lazy
Respuesta #2
Supuse que puedes extender la cadena yup de la siguiente manera:
class StrictString extends yup.string {
constructor() {
super();
transforms = []; // remove the default type coercion transforms
}
}
Y luego, reemplaza StrictString() con yup.string(). Esto cumplirá con los requisitos.
