0
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?

Zodのcoerce機能で解決:HTMLのinput type="number"が文字列になる問題

Posted at

🤔 こんな問題に悩んでいませんか?

<input type="number" id="count" />

👆 このフォーム要素、見た目は数値入力用なのに、JavaScript側では、

const value = document.getElementById('count').value;
console.log(typeof value); // "string" 😱

文字列として扱われてしまいます!

📝 よくある解決パターン

こんな解決パターンを見かけることがあります。

// フォーム用とサーバー用、2つの型定義を作成
interface FormData {
  count: string;  // フォームからの入力は文字列
}

interface ProcessedData {
  count: number;  // 処理時は数値
}

このパターンだと、コードが冗長になり、型の不一致によるバグも発生しやすい問題があります。

✅ Zodのcoerce機能で解決!

Zodのcoerce.number()を使えば、この問題を解決できます。

import { z } from "zod";

// たった1つの型定義でOK! 🎉
const formSchema = z.object({
  count: z.coerce.number().int().min(1)
});

type FormData = z.infer<typeof formSchema>;

🚀 React Hook Formでの実装例

import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";

function CounterForm() {
  const { register, handleSubmit } = useForm<FormData>({
    resolver: zodResolver(formSchema)
  });

  const onSubmit = (data: FormData) => {
    console.log(typeof data.count); // "number" 🎯
    // 数値として直接計算できる!
    const doubled = data.count * 2;
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input type="number" {...register("count")} />
      <button type="submit">送信</button>
    </form>
  );
}

⚡ Next.jsのServer Actionsでも

'use server'

// Server Actionsでも同じスキーマが使える! 🔄
export async function saveCount(formData: FormData) {
  const data = formSchema.parse({
    count: formData.get('count')
  });
  
  // data.countは既に数値型 🧮
  // データベースに保存する処理...
}

💡 coerce.number()のポイント

  • 空文字列 → 0 に変換
  • 文字列 "123" → 数値 123 に変換
  • バリデーションも同時に設定可能(.int().min()など)

🌟 メリット

  • 型定義の一元化: フォーム用とサーバー用で別々の型が不要に
  • コードの簡素化: 変換処理を書く手間が省ける
  • 型安全性の向上: フォーム入力からサーバー処理まで一貫した型で扱える

🎯 まとめ

Zodのcoerce.number()を使えば、HTMLの<input type="number">から取得した値が文字列型になる問題をサクッと解決できます。コードはシンプルに、型安全性は向上し、開発効率もアップします!

0
0
1

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
0
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?