この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
どうもこんにちは、稲葉です。
最近、私はTypeScriptを使ってちょっとした開発をしていたので、便利なライブラリやフレームワークを探していました。その中で、ゾッと驚くものを見つけたんです。
それが、TypeScriptファーストのスキーマ宣言・検証ライブラリであるZodです。
Zodの素晴らしさは、実際に触ってみないとわからないと思います。私自身もZodを使ってみて、その使いやすさに感動しました。
そこで、今回はZodライブラリの基本的な使い方を紹介したいと思います!
あなたもZodの魅力に触れてみませんか?
準備
React使って進めていきます。 はじめにターミナルで以下のコマンドを打ちます。
npx create-react-app my-app --template typescript
cd my-app
npm start
TypeScriptをテンプレートに指定して、create-react-appで必要なものを一式揃えます。
インストールが完了しましたら、my-appに移動して、npm startで動くか確かめます。
少し経つとブラウザが起動して、このような画面が開かれると思います。
Zodをインストールする前に、App .tsxファイルを編集して、簡単なお問い合わせフォームを作っていきます。
/src/App.tsx
import "./App.css";
import React, { useState } from "react";
interface FormData {
name: string;
email: string;
message: string;
}
const App: React.FC = () => {
const [formData, setFormData] = useState<FormData>({
name: "",
email: "",
message: "",
});
const handleChange = (
event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
setFormData({ ...formData, [event.target.name]: event.target.value });
};
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
console.log(formData);
};
return (
<div className="App">
<h2>お問い合わせフォーム</h2>
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" name="name" value={formData.name} onChange={handleChange} />
</label>
<label>
Email:
<input type="email" name="email" value={formData.email} onChange={handleChange} />
</label>
<label>
Message:
<textarea name="message" value={formData.message} onChange={handleChange} />
</label>
<button type="submit">Submit</button>
</form>
</div>
);
};
export default App;
ファイルを保存して、ターミナルで以下のコマンドを打ち、
npm start
もう一度起動すると、このような画面になります。
今回はZodのお試しなので、フォームには特にCSSは当てていません。
何かしら入力してSubmitボタンを押して、Chromeの検証ツールでConsoleを見ると、
上記のように出力されます。
これで準備は完了です!これからZodを実装していきます。
Zod実装
インストール
はじめにZodをインストールします。
npm install zod
それでは、コードを書いていきます。
/src/App.tsx
import "./App.css";
import { z } from "zod";
import React, { useState } from "react";
// 以下略
まず、import { z } from "zod"でZodをインポート。
const age = z.number().min(1);
const url = z.string().url();
Zodはこのようにシンプルな数値のスキーマやURL文字列のスキーマを宣言する事ができます。
.object()
今回はお問い合わせフォームの複数の入力値に対して設定したいので、
Zodのオブジェクトスキーマを使います。
/src/App.tsx
const App: React.FC = () => {
const [formData, setFormData] = useState<FormData>({
name: "",
email: "",
message: "",
});
const FormData = z.object({
name: z.string().min(2).max(50),
email: z.string().email(),
message: z.string().min(5),
});
オブジェクトスキーマは、.object()で定義していきます。
- nameに対して、最小2文字、最大50字の文字列
- emailに対して、メール形式の文字列
- messageに対して、最小5文字の文字列
と言った感じにバリデーションを設定しました。
.infer<T>
.inferを使うことで、スキーマを利用してTypescriptの型を生成できます。
なので、FormDataスキーマからCopyと言う型を作りたいと思います。
const FormData = z.object({
name: z.string().min(2).max(50),
email: z.string().email(),
message: z.string().min(5),
});
type Copy = z.infer<typeof FormData>;
Copyの所にカーソルを持っていくと以下のように表示されると思います。(エディターはVScodeを使ってます)
CopyはFormDataスキーマと同じ型を持っています。
このようにinfer関数を使えば簡単に型を作成する事ができます。
.parse()
//
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const result = FormData.parse(formData);
console.log(result);
console.log(formData);
};
//
先ほど定義したスキーマを使って、 handleSubmitで.parse()という関数を使い検証していきます。
.parse()は、入力値がスキーマの期待する値かを検証します。
試しにフォームに何も入力しないで、Submitボタンを押してみてください。
恐らく、上記のようなエラー画面が表示されると思います。このように.parse()は、検証に失敗するとエラーを投げます。
次に、
- name = test
- email = abc@abc.com
- message = zazizuzezo
を入力して、Submitボタンを押します。そうすると、入力値が期待する値だったため、コンソールに以下のように出力されます。
.parse()は、検証に成功すると入力値を返します、
.safeParse()
.safeParse()と言う検証する関数もあります。先ほどの.parse()とは、入力値を検証する点は同じなのですが、戻り値が違います。
その点を実際に動かして確かめたいと思います。
//
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const result = FormData.safeParse(formData);
console.log(result);
console.log(formData);
};
//
また、フォームに何も入力しないでSubmitボタンを押します。
そうするとコンソールに、エラー内容とsuccessプロパティのfalseが出力されます。
このように、.safeParse()は戻り値をSuccessプロパティを含むオブジェクトとして返します。
今度は検証に成功するように入力して、Submitボタンを押します。
先ほどとは違い、入力値とsuccessプロパティのtrueが出力されました。
まとめ
今回はZodライブラリの基本的な使い方を紹介しました!
お問い合わせフォームの作成だったため、基本的なZodの使い方しか紹介できませんでしたが、
少しでもZodに興味を持って頂けたら幸いです。
今後も何かしら気になるフレームワークやライブラリがありましたら、投稿したいと思います。
以前に書いたFastAPIの記事も興味がありましたら、読んでもらえると嬉しいです!
https://dev.classmethod.jp/articles/try_fastapi_intro/
最後まで読んで下さり、ありがとうございます。