はじめに
この記事はデータフェッチ時に zod のバリデーションを使用することでフェッチしたデータ型を保障することから フォームバリデーション 以外での zod の使い方の備忘録です。
間違っている部分がありましたらコメントで教えてもらえると嬉しいです。
parseメソッド
zod でバリデーションを行う時は
判定するバリデーションルールを記述した zodスキーマ を作成し
zodスキーマ の parseメソッド か safeparseメソッド を使います。
const mySchema = z.string().min(1);
const parsedValue = mySchema.parse("abc");
console.log(parsedValue); //"abc"
const parsedValue2 = mySchema.parse(123);
console.log(parsedValue2); // エラーがスローされるのでログが流れない
parseメソッド では
バリデーション 成功時 は バリデーションの引数の値が戻り値となり
バリデーション 失敗時 は エラーがスローされます。
エラーの内容を取得するには
try-catch
で parseメソッド を囲んで
error.flatten() で 取得できます。
バリデーションエラー の時のみエラー内容を取得する必要があるので、
error instance of ZodError で判定します。
try {
const parsedValue2 = mySchema.parse(123);
console.log(parsedValue2); // エラーがスローされるのでログが流れない
} catch (e) {
if (e instanceof ZodError) {
console.log(e.flatten()); // { formErrors: [ 'Expected string, received number' ], fieldErrors: {} }
}
}
safeParseメソッド
safeParseメソッド では
バリデーション 成功時 は success: true で data: バリデーションの引数 なオブジェクトが
バリデーション 失敗時 は success: false で error: エラー内容が詰まったオブジェクト
なオブジェクトが返されます。
const mySchema = z.string().min(1);
const parsedValue = mySchema.safeParse("abc");
console.log(parsedValue); // { success: true, data: 'abc' }
const parsedValue2 = mySchema.safeParse(123);
console.log(parsedValue2); // { success: false, error: [Getter] }
console.log(parsedValue2.error.flatten()); // { formErrors: [ 'Expected string, received number' ], fieldErrors: {} }
エラーの内容を取得するには
error.flatten() で取得します。
ただし、success: false でないと errorプロパティが存在しない ので
success: false であることを判定してからでなければなりません。
なので、正しくはこのように記述します。
const mySchema = z.string().min(1);
const parsedValue = mySchema.safeParse("abc");
console.log(parsedValue); // { success: true, data: 'abc' }
const parsedValue2 = mySchema.safeParse(123);
console.log(parsedValue2); // { success: false, error: [Getter] }
console.log(parsedValue2.success ? {} : parsedValue2.error.flatten()); // { formErrors: [ 'Expected string, received number' ], fieldErrors: {} }
フェッチしたデータにバリデーションチェックを行うことでデータ型を保障する
jsonplaceholder
からフェッチしたデータをバリデーションチェックします。
import { z } from "zod"
const todoSchema = z.object({
userId: z.number(),
id: z.number(),
title: z.string(),
completed: z.boolean(),
});
const fetchTodos = await fetch("https://jsonplaceholder.typicode.com/todos");
const fetchTodo = await fetchTodos.json();
const parsedTodo = todoSchema.safeParse(fetchTodo[0]);
console.log(parsedTodo);
/*{
success: true,
data: { userId: 1, id: 1, title: 'delectus aut autem', completed: false }
}
*/
このようにしてフェッチしたデータのデータ型を保障します。
zodスキーマからTSのデータ型を取得する
zodスキーマ からTSの型を取得する方法も記述しておきます。
import { z } from "zod"
const UserSchema = z.object({
username: z.string(),
});
type User = z.infer<typeof UserSchema>
/*
type User = {
username: string;
}
*/
zodスキーマ を定義した後に
z.infer<typeof zodスキーマ> で zodスキーマのデータ型 を取得出来ます。
さいごに
学習させていただいた先・ライブラリの公式ドキュメントです。