1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【備忘録】データフェッチ時に zod を使ってフェッチしたデータのデータ型を保障する

Last updated at Posted at 2024-03-21

はじめに

この記事はデータフェッチ時に 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-catchparseメソッド を囲んで
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: truedata: バリデーションの引数 なオブジェクトが
バリデーション 失敗時success: falseerror: エラー内容が詰まったオブジェクト
なオブジェクトが返されます。

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スキーマのデータ型 を取得出来ます。

さいごに

学習させていただいた先・ライブラリの公式ドキュメントです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?