7つのデータ型
Yupは入力項目の特性を宣言的に記載することでスキーマを組み立て、バリデーション処理を実施できるライブラリだということをここまでに解説しました。次は、Yupでどんなデータをバリデーションできるのかを見ていきましょう。Yupが取り扱うデータ型は、大別すると7つに分類できます。
- mixed:共通データ型
- string:文字列型
- number:数値型
- boolean:真偽値型
- date:日付型
- array:配列型
- object:オブジェクト型
共通データ型ジャンルの関数群だけは少し特殊で、どんなデータ型にも当てはまるrequired()関数などが当てはまります。他のデータ型については「本当にそのデータ型の値が入力されたか」がチェックされ、その上で「大きい、小さい」「長い、短い」などの条件がチェックされることになります。それでは、フォーム実装でよく使う項目を中心に、どんな条件付けができるのかを見ていきましょう。
mixed:共通データ型
mixed()でスキーマを作った場合、その項目はすべてのデータ型を受け入れます。例えば、リスト5のようにundefinedを入力値として渡しても、バリデーションが成功します。
const schema = yup.mixed();
schema.isValid(undefined, function (valid) {
valid; // => true
});
何らかの理由で複雑なデータ型をフォームで扱うことになり、データ型のチェックをしたくない場合にmixed()を利用するとよいでしょう。またmixed()に付けられるバリデーション条件は、他のすべてのデータ型に同じものを定義できるので、汎用性が高いものになっています。
-
required():必須項目である -
default(any):入力値がない場合のデフォルト値を指定する -
oneOf(array):複数の項目のうちどれか1つならばOK
required()は、これまでの解説にも出てきた通り、フォームのUIに頻出する必須項目を扱います。default()は、入力項目がundefinedだった場合にデフォルト値を割り当てるために利用します。validate()関数が成功したときに渡される値は元の入力値そのままではなく、このdefault()で割り当てた値で置き換えることもできるということです。oneOf()は、事前に定義した1つまたは複数の値に入力値が含まれているかをチェックする、少しユニークな条件です。リスト6のように使います。
const schema = yup.mixed().oneOf(['jiro', 10]); // (1)
await schema.isValid(10); // => true // (2)
await schema.isValid('jiro'); // => true // (3)
await schema.isValid(new Date()); // => false // (4)
(2)と(3)の値は(1)の配列に含まれているので、バリデーションで正常と判定されます。一方、(4)はDate型の値なのでエラー扱いとなります。ドロップダウンなどの選択式のUIで、入力値の候補がいくつかに絞られる場合には、有効な選択肢となるでしょう。
string:文字列型
string()で作ったスキーマは入力値を文字列としてチェックします。文字列は入力フォームにとって最も基本的なデータ型なので、チェック項目も多様です(リスト7)。
// 文字列ならOK
await yup.string().isValid('こんにちは'); // => true
// 必須入力
await yup.string().required().isValid('hi'); // => true
// 必須入力の場合に空文字は不正となる
await yup.string().required().isValid(''); // => false
// 指定した文字数以外だとエラー
await yup.string()
.length(5, '入力値は5文字ちょうどで入力してください').isValid('aaaaaa'); // => false
// 指定した最小文字数より小さいとエラー
await yup.string()
.min(5, '入力値は5文字以上にしてください').isValid('aaa'); // => false
// 指定した最大文字数より大きいとエラー
await yup.string()
.max(5, '入力値は5文字以下にしてください').isValid('aaa'); // => true
// 正規表現にマッチしなければエラー
await yup.string().matches(/(dog|cat)/).isValid('bird'); // => false
// メールアドレスの仕様に沿っていなければエラー
await yup.string().email().isValid('aaaa@example.com'); // => true
// URLの仕様に沿っていなければエラー
await yup.string().url().isValid('https://example.com'); // => true
入力文字数に関するバリデーションは特に重宝するので、覚えておくとよいでしょう。
number:数値型
number()で作ったスキーマは入力値を数値としてチェックします(リスト8)。
// 数値ならOK await yup.number().isValid(10); // => true // 指定した最小値より小さいとエラー await yup.number().min(5).isValid(3); // => false // 指定した最大値より大きいとエラー await yup.number().max(5).isValid(5); // => true // 指定した最大値以上だとエラー await yup.number().lessThan(5).isValid(5); // => false await yup.number().lessThan(5).isValid(4); // => true // 指定した最小値以下だとエラー await yup.number().moreThan(5).isValid(5); // => false await yup.number().moreThan(5).isValid(6); // => true // 正の値ならOK await yup.number().positive().isValid(5); // => true // 負の値ならOK await yup.number().negative().isValid(-5); // => true // 整数ならOK await yup.number().integer().isValid(1.1); // => false
数値の境界値チェックに便利な条件が整備されていますね。
boolean:真偽値型
boolean()で作ったスキーマは入力値を真偽値としてチェックします(リスト9)。
// 真偽値ならOK await yup.boolean().isValid(true); // => true
boolean()は2値しかないので、バリデーションルールは特に整備されていません。
date:日付型
date()で作ったスキーマは入力値を日付型としてチェックします(リスト10)。
// Date型ならOK
await yup.date().isValid(new Date()); // => true
// ISO8601形式の文字列でもOK
await yup.date().isValid('2020-12-24T03:17Z'); // => true
// 指定した日付以降ならOK
await yup.date().min('2020-12-23').isValid('2020-12-24'); // => true
// 指定した日付以前ならOK
await yup.date().max('2020-12-23').isValid('2020-12-22'); // => true
日時の範囲を指定できるのは便利ですね。
array:配列型
array()で作ったスキーマは配列で渡された入力値の集合についてチェックします(リスト11)。
// 配列ならOK await yup.array().isValid([1, 2]); // => true // 他のデータ型で縛ることもできる await yup.array(yup.string()).isValid(['a', 'b']); // => true await yup.array(yup.string()).isValid([1, 2]); // => false // 配列が指定した長さではない場合にエラー await yup.array().length(5).isValid([1, 2]); // => false // 配列が指定した長さより小さい場合にエラー await yup.array().min(5).isValid([1, 2]); // => false // 配列が指定した長さより大きい場合にエラー await yup.array().max(5).isValid([1, 2]); // => true // 配列内の値もチェックできる await yup .array(yup.number().min(2)).isValid([1, 2]); // => false (2より小さい数値が含まれているため)
複数回答を許可しているフォームなどで威力を発揮する機能ですね。
object:オブジェクト型
object()で作ったスキーマはオブジェクトで渡された入力値の集合についてチェックします。Formikをはじめとして、フォームの入力値をデータとして表現する場合にはオブジェクトの形になることが多いため、スキーマの最上位のデータ型として重宝します(リスト12)。
// shapeで項目ごとのチェック条件を定義できる
yup.object().shape({
name: yup.string().required(),
age: yup.number().required().positive().integer(),
email: yup.string().email(),
});
オブジェクトで最上位のデータ構造を定義し、個別のデータ構造はstring()やnumber()で定義するのがよくあるスタイルになります。
