最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I allow a field to be undefined while disallowing type coercion using Yup? - Stack Overflow

programmeradmin1浏览0评论

I'm trying to validate an object's field using yup.

These are my requirements:

  1. The field should either be a string or undefined.
  2. If it is undefined, it should be given a default value.
  3. 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:

  1. The field should either be a string or undefined.
  2. If it is undefined, it should be given a default value.
  3. 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 badges
Add a ment  | 

2 Answers 2

Reset to default 3

Yup 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.

发布评论

评论列表(0)

  1. 暂无评论