Zodでスキーマオブジェクトを使い回す方法
こんにちは。中塚です。
はじめに
Zodは、TypeScriptのためのスキーマ宣言と検証のライブラリで、オブジェクトのバリデーションを簡単に行うことができます。この記事では、Zodを使用してスキーマオブジェクトを効率的に使い回す方法について説明します。今回は、動物園をテーマに例を作成し、動物データのスキーマを入力フォームとAPIで再利用する方法をご紹介いたします。
Zodの基本
まずは、基本的なZodの使い方をおさらいいたします。以下のコードでは、AnimalSchema
を定義しています。
import { z } from "zod";
const AnimalSchema = z.object({
id: z.string(),
name: z.string(),
species: z.string(),
age: z.number().nullable(),
habitat: z.string(),
});
type Animal = z.infer<typeof AnimalSchema>;
このスキーマは、動物のID、名前、種、年齢、および生息地を表すフィールドを持っています。
スキーマオブジェクトの使い回し
同じスキーマを異なるコンテキストで使いたい場合、Zodのオブジェクトを再利用することができます。例えば、動物のデータを入力フォームとAPIの両方で使用したい場合、以下のように定義します。
// AnimalSchemaのキーをAPIのSchemaから取得
const animalKeys = getKeyMapping(AnimalSchema.shape);
// 入力フォーム用スキーマ
export const AnimalFormValuesSchema = z
.object({
[animalKeys.id]: z.string(),
[animalKeys.name]: z.string(),
[animalKeys.species]: z.string(),
[animalKeys.age]: createNumberInputSchema({ defaultValue: null }),
[animalKeys.habitat]: z.string(),
});
getKeyMapping
関数を使用することで、スキーマキーを動的に取得し、コードの一貫性と再利用性を高めることができます。
入力フォーム用スキーマの作成
入力フォームで使用するスキーマには、特定のバリデーションロジックやデフォルト値を設定する必要があります。以下のコードは、数値入力フィールドのスキーマを作成するためのヘルパー関数です。
(コードフォロー時にご教示いただきました。)
export const createNumberInputSchema = <T>({
defaultValue,
errorMessage = i18n.t('constants.common.FORM.INVALID_NUMBER'),
}: {
defaultValue?: T;
errorMessage?: string;
}) =>
z.string().transform((value, ctx) => {
const asNum = Number(toHalfWidth(value));
if (value !== '' && Number.isNaN(asNum))
ctx.addIssue({
code: 'custom',
message: errorMessage,
});
return value === '' ? defaultValue : asNum;
});
入力欄が空の場合、NaNとなり厄介です。
この関数は、文字列として入力された値を数値に変換し、変換できない場合にはカスタムエラーメッセージを追加します。また、空文字の場合にはデフォルト値を返します。
スキーマのマージ
Zodを使用すると、スキーマオブジェクトをマージすることができ、異なるスキーマを統合して一貫性を持たせることが可能です。たとえば、以下のように既存のスキーマをマージして、新しいスキーマを作成できます。部分的にピックすることで、必要なフィールドだけを含むスキーマを簡単に作成できます。
// AnimalSchemaのキーを取得
const animalKeys = getKeyMapping(AnimalSchema.shape);
// 入力フォーム用スキーマ
export const AnimalFormValuesSchema = z
.object({
[animalKeys.age]: createNumberInputSchema({ defaultValue: null }),
}).merge(AnimalSchema.pick({
id: true,
name: true,
species: true,
habitat: true,
}));
このコードでは、AnimalSchema
のキーを動的に取得し、数値入力部分以外のフィールドをpick
することで、必要なフィールドだけを含むスキーマを作成しています。
まとめ
Zodを使うことで、スキーマオブジェクトを効率的に使い回すことができます。これにより、重複するコードを減らし、メンテナンス性を向上させることができます。
Discussion