Zod: TypeScript 스키마 검증

2025. 2. 20. 10:46·TypeScript
반응형
# 설치
npm install zod

기본 사용법

import { z } from "zod";

// 기본 스키마 정의
const userSchema = z.object({
  name: z.string(),
  age: z.number().min(0),
  email: z.string().email(),
  website: z.string().url().optional()
});

// 타입 추론
type User = z.infer<typeof userSchema>;

// 데이터 검증
try {
  const user = userSchema.parse({
    name: "John",
    age: 30,
    email: "john@example.com"
  });
} catch (error) {
  console.error(error);
}

고급 스키마 정의

const addressSchema = z.object({
  street: z.string(),
  city: z.string(),
  country: z.string()
});

const userProfileSchema = z.object({
  id: z.number(),
  username: z.string().min(3).max(20),
  email: z.string().email(),
  age: z.number().min(18).max(100),
  isActive: z.boolean(),
  address: addressSchema,
  tags: z.array(z.string()).min(1).max(5),
  settings: z.record(z.string(), z.any())
});

조건부 검증

const passwordSchema = z.object({
  password: z.string()
    .min(8, "비밀번호는 최소 8자 이상이어야 합니다")
    .regex(/[A-Z]/, "대문자를 포함해야 합니다")
    .regex(/[0-9]/, "숫자를 포함해야 합니다"),
  confirmPassword: z.string()
}).refine((data) => data.password === data.confirmPassword, {
  message: "비밀번호가 일치하지 않습니다",
  path: ["confirmPassword"]
});

유니온 타입과 열거형

const Role = z.enum(["admin", "user", "guest"]);

const UserStatus = z.union([
  z.literal("active"),
  z.literal("inactive"),
  z.literal("pending")
]);

const userSchema = z.object({
  id: z.number(),
  role: Role,
  status: UserStatus,
  data: z.discriminatedUnion("type", [
    z.object({ type: z.literal("admin"), permissions: z.array(z.string()) }),
    z.object({ type: z.literal("user"), subscription: z.string() })
  ])
});

React와 함께 사용

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

const formSchema = z.object({
  username: z.string().min(3),
  email: z.string().email(),
  age: z.number().min(18)
});

function Form() {
  const { register, handleSubmit, formState: { errors } } = useForm({
    resolver: zodResolver(formSchema)
  });

  return (
    <form onSubmit={handleSubmit(data => console.log(data))}>
      <input {...register("username")} />
      {errors.username && <span>{errors.username.message}</span>}

      <input {...register("email")} />
      {errors.email && <span>{errors.email.message}</span>}

      <input {...register("age", { valueAsNumber: true })} />
      {errors.age && <span>{errors.age.message}</span>}

      <button type="submit">제출</button>
    </form>
  );
}

트랜스폼과 파싱

const numberString = z.string().transform((val) => parseInt(val));
const dateString = z.string().transform((val) => new Date(val));

const formDataSchema = z.object({
  userId: numberString,
  joinDate: dateString,
  preferences: z.string().transform((val) => JSON.parse(val))
});

비동기 검증

const asyncSchema = z.object({
  username: z.string().refine(async (value) => {
    const response = await fetch(`/api/check-username/${value}`);
    return response.ok;
  }, "이미 사용 중인 사용자 이름입니다")
});

// 사용 예시
async function validateUsername(data) {
  try {
    await asyncSchema.parseAsync(data);
    return true;
  } catch (error) {
    return false;
  }
}

 

장점

  1. 타입 안전성
    • TypeScript와 완벽한 통합
    • 런타임 타입 검증
  2. 유연성
    • 복잡한 스키마 정의 가능
    • 커스텀 검증 로직 지원
  3. 사용 편의성
    • 직관적인 API
    • 체이닝 방식의 검증 규칙
  4. 성능
    • 효율적인 검증 처리
    • 최적화된 타입 추론

Zod는 TypeScript 프로젝트에서 데이터 검증을 위한 강력한 도구로, 특히 폼 처리와 API 응답 검증에 매우 유용합니다.

저작자표시 비영리 변경금지 (새창열림)

'TypeScript' 카테고리의 다른 글

Next.js에서 cookies-next로 쿠키 관리하기  (2) 2025.03.22
tailwind CSS : 유틸리티 기반 CSS 프레임워크  (0) 2025.03.01
React Hook Form: 폼 상태 관리  (0) 2025.02.19
Node-Cache : 서버 성능 최적화  (0) 2025.02.17
React : map  (0) 2025.02.16
'TypeScript' 카테고리의 다른 글
  • Next.js에서 cookies-next로 쿠키 관리하기
  • tailwind CSS : 유틸리티 기반 CSS 프레임워크
  • React Hook Form: 폼 상태 관리
  • Node-Cache : 서버 성능 최적화
코샵
코샵
나의 코딩 일기장
    반응형
  • 코샵
    끄적끄적 코딩 공방
    코샵
    • 분류 전체보기 (727)
      • 스마트팜 (1)
      • 상품 추천 (223)
      • DataBase (0)
        • MongoDB (4)
        • PostgreSQL (0)
      • 하드웨어 (18)
      • 일기장 (4)
      • 파이썬 (130)
        • Basic (41)
        • OpenCV (8)
        • Pandas (15)
        • PyQT (3)
        • SBC(Single Board Computer) (1)
        • 크롤링 (14)
        • Fast API (29)
        • Package (6)
      • Unity (138)
        • Tip (41)
        • Project (1)
        • Design Pattern (8)
        • Firebase (6)
        • Asset (2)
      • Linux (4)
      • C# (97)
        • Algorithm (11)
        • Window (7)
      • TypeScript (51)
        • CSS (10)
      • Git (11)
      • SQL (5)
      • Flutter (10)
        • Tip (1)
      • System (1)
      • BaekJoon (6)
      • Portfolio (2)
      • MacOS (1)
      • 유틸리티 (1)
      • 서비스 (6)
      • 자동화 (3)
      • Hobby (10)
        • 물생활 (10)
        • 식집사 (0)
  • 인기 글

  • 태그

    긴유통기한우유
    cv2
    스크립트 실행
    쇼핑몰리뷰
    appdevelopment
    셀레니움
    스마트스토어리뷰
    카페24리뷰이관
    devlife
    codingtips
    rtsp
    파이썬
    list
    Python
    믈레코비타멸균우유
    리뷰이관
    ipcamera
    라떼우유
    유니티
    카페24리뷰
    programmerlife
    상품 리뷰 크롤링
    스크립트 실행 순서
    programming101
    리스트
    learntocode
    unity
    C#
    codingcommunity
    리뷰관리
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
코샵
Zod: TypeScript 스키마 검증
상단으로

티스토리툴바