반응형
# 설치
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;
}
}
장점
- 타입 안전성
- TypeScript와 완벽한 통합
- 런타임 타입 검증
- 유연성
- 복잡한 스키마 정의 가능
- 커스텀 검증 로직 지원
- 사용 편의성
- 직관적인 API
- 체이닝 방식의 검증 규칙
- 성능
- 효율적인 검증 처리
- 최적화된 타입 추론
Zod는 TypeScript 프로젝트에서 데이터 검증을 위한 강력한 도구로, 특히 폼 처리와 API 응답 검증에 매우 유용합니다.
'TypeScript' 카테고리의 다른 글
React Hook Form: 폼 상태 관리 (0) | 2025.02.19 |
---|---|
Node-Cache : 서버 성능 최적화 (0) | 2025.02.17 |
React : map (0) | 2025.02.16 |
React useEffect 의존성 경고 (1) | 2025.02.14 |
Nginx 413 Request Entity Too Large 오류 해결 (0) | 2025.02.13 |