Skip to main content

[note] Yup 筆記

Yup @ Github

mixed.validate:檢驗 value 是否符合 schema#

mixed.validate(value: any, options?: object): Promise<any, ValidationError>

可以用來檢驗 value 和 schema 是否相符合:

import {
number as yupNumber,
object as yupObject,
string as yupString,
ValidationError,
} from 'yup';
const schema = yupObject().shape({
name: yupString().required(),
age: yupNumber().min(18).required(),
});
schema
.validate({
name: 'Aaron',
age: 'foo',
})
.then((value) => console.log({ value }))
.catch((err: ValidationError) => {
const { errors, name } = err;
console.log({
name,
errors,
});
});

mixed.cast:根據 schema 把 value 作轉換後輸出#

mixed.cast(value: any, options = {}): any

透過 cast 只會將資料做轉換,例如把字串 '10' 變成數值 10不會做驗證(validate)的動作

const schema = yupObject().shape({
name: yupString().required(),
age: yupNumber().min(18).required(),
});
const value = schema.cast({
name: 'Aaron',
age: '10',
});
// { age: 10, name: 'Aaron' }

mixed.default:用來將 schema 中的欄位設定預設值#

mixed.default(value: any): Schema

const schema = yupObject().shape({
name: yupString().required().default('Aaron'),
age: yupNumber().min(18).required(),
});
const defaultValue = schema.getDefault(); // { age: undefined, name: 'Aaron' }
const value = schema.cast({ age: '10' }); // { age: 10, name: 'Aaron' }

mixed.when:根據 schema 中的其他欄位來改變驗證的規則#

mixed.when(keys: string | Array<string>, builder: object | (value, schema) => Schema): Schema

builder 中可以直接帶入物件,其中包含屬性

  • is:該欄位的值是,預設會用 === 比較,也可以帶入 function
  • then:若 is 的條件滿足 true,則會使用這裡的規則
  • otherwise:若 is 的條件為 false,則會使用這裡的規則
const schema = yupObject().shape({
isBig: yupBool(),
count: yupNumber().when('isBig', {
is: true, // 當 isBig 的值是 true
then: yupNumber().min(10), // 當 is 成立時,則使用 then 的規則(count >= 10)
otherwise: yupNumber().max(5), // 當 is 不成立時,則使用 otherwise 的規則(count <= 5)
}),
});
schema
.validate({
isBig: false, // 根據 isBig 的值來決定 count 驗證的邏輯
count: 7,
})
.then(value => value)
.catch(err => err);

when 的第二個參數也可以放函式:

const schema = yupObject().shape({
isBig: yupBool(),
count: yupNumber()
.when('isBig', (value: boolean, schema: NumberSchema) =>
// 如果 isBig 為 true,則驗證 count 的值是否 >= 10,否則驗證是否 <= 5
value ? schema.min(10) : schema.max(5)
),
});
schema
.validate(
{
isBig: true, // 根據 isBig 的值來決定 count 驗證的邏輯
count: 9,
}
)

也可以搭配 context 使用,或同時串接多個 when 使用:

const schema = yupObject().shape({
isBig: yupBool(),
count: yupNumber()
.when('isBig', (value: boolean, schema: NumberSchema) =>
// isBig 為真,count 需 >= 10;否則 count <= 5
value ? schema.min(10) : schema.max(5)
)
.when('$type', (type: string, schema: NumberSchema) =>
// $type 等於 "NARROW" 則 count 需 <= 3
type === 'NARROW' ? schema.max(3) : schema
),
});
schema
.validate(
{
isBig: false,
count: 4,
},
// context 中定義 type 這個變數
{ context: { type: 'NARROW' } }
)
.then(value => value).catch(err => err)

也可以根據多個變數來決定要使用的規則:

const schema = yupObject().shape({
isBig: yupBool(),
// 同時根據 isBig 和 isNarrow 來決定要用哪個驗證邏輯F
count: yupNumber().when(['isBig', 'isNarrow'], {
is: (isBig: boolean, isNarrow: boolean) => !isBig && isNarrow,
then: yupNumber().min(2),
otherwise: yupNumber().max(10),
}),
});
schema
.validate({
isBig: false,
isNarrow: true,
count: 4,
})
.then(value => value).catch(err => err)

mixed.test:用來建立自訂的驗證邏輯#

mixed.test(name: string, message: string | function, test: function): Schema

除了 Yup 針對個型別內建的規則之外(例如,min(), oneOf())透過 test 可以建立客製化的驗證規則,其中 test 必須包含

  • name: string
  • message: string | function:驗證錯誤時顯示的訊息,在 message 中可以透過 ${} 的方式,把 testContext.params 中的參數自動替換進去。
  • test: function:用來驗證的規則,回傳 true (valid)、false(invalid)
const customSchema = yupString().test(
'is-aaron', // name
'${path} is not Aaron', // message
(value, testContext) => {
if (value !== 'Aaron') {
// 產生錯誤訊息
return testContext.createError({
message: '${originalValue} is not Aaron',
});
}
return value === 'Aaron';
}
);
// valid
customSchema
.validate('Aaron')
.then((value) => console.log(value))
.catch((err) => console.log(err));
// invalid
customSchema
.validate('aaron')
.then((value) => console.log(value))
.catch((err: ValidationError) =>
console.log({
name: err.name,
message: err.message,
errors: err.errors,
})
);
// {
// name: 'ValidationError',
// message: 'aaron is not Aaron',
// errors: [ 'aaron is not Aaron' ]
// }

test 除了可以透過帶入多個參數的方式,也可以透過帶入物件的方式來使用:

const customSchema = yupString().test({
name: 'is-aaron',
test: (value) => value === 'Aaron',
params: { expect: 'Aaron' }, // 這裡的值會可以被帶到 message 中使用
message: '${value} is not ${expect}',
});
customSchema
.validate('aaron')
.then((value) => console.log(value))
.catch((err: ValidationError) =>
console.log(err)
);
Last updated on