
다른 사람들의 깃허브 코드를 볼때 zod를 많이 사용하던데 이게 뭐지 ? 라고 느끼게 되면서
따로 공부해야겠다 마음은 먹었지만 제대로 확인해보는 것을 못했는데 이번에 시간내서 공부하게 되었다.
그래서 오늘은 Zod에 대해 정리해봤다.
TypeScript를 쓰다 보면 “타입이 있으니까 안전하다”고 생각하기 쉬운데,
실제로는 런타임에서 들어오는 값들은 전혀 안전하지 않다는 걸 자주 느끼게 된다.
Zod는 바로 그 지점을 해결하기 위한 라이브러리다.
Zod는 TypeScript-first 스키마 선언 & 검증 라이브러리다.
한 줄 요약
“타입을 검사하는 코드와 타입 정의를 하나로 합친 도구”
TypeScript의 타입은 컴파일 타임에만 존재한다.
type User = {
name: string
}
이 타입은 런타임에서는 완전히 사라진다.
즉, 아래 코드는 TypeScript가 막아주지 못한다.
const user = JSON.parse(input) // unknown
API 요청 데이터,외부 API 응답,form 입력,env 값
이부분에서 Zod를 사용한다.
런타임에서 실제 값 검증
검증된 값만 타입으로 사용 가능
import { z } from 'zod'
const UserSchema = z.object({
name: z.string(),
age: z.number(),
})
검증
UserSchema.parse(data)
// 실패 시 예외 throw
UserSchema.safeParse(data)
// 성공/실패 객체 반환
const result = UserSchema.safeParse(data)
if (!result.success) {
console.log(result.error)
}
const UserSchema = z.object({
name: z.string(),
age: z.number(),
})
type User = z.infer
Zod 스키마를 TypeScript 타입으로 변환
타입 정의 중복 제거
-> Zod의 핵심 장점 중 하나
type UserInput = z.input
| 구분 | 의미 |
|---|---|
| z.infer | parse 이후의 타입 |
| z.input | parse 이전 입력 타입 |
zodResolver는 Zod를 React Hook Form과 연결해주는 어댑터다.
import { zodResolver } from '@hookform/resolvers/zod'
form 입력값을 Zod 스키마로 검증
에러를 React Hook Form 형식으로 변환
const schema = z.object({
email: z.string().email(),
password: z.string().min(8),
})
useForm({
resolver: zodResolver(schema),
})
장점
form validation 로직 제거
타입 + 검증 로직 통합
에러 메시지 일관성 유지
z.string()
.min(1)
.max(20)
.email()
z.string().min(n)
z.string().max(n)
z.string().email()
z.number().int()
z.number().positive()
z.boolean()
z.array(schema)
z.optional()
z.nullable()
z.string().optional()
z.string().nullable()
무분별하게 사용하면 데이터 검증을 여러번 해서 성능측면에서 좋지 않다.
Zod는 “신뢰할 수 없는 입력”에서만 사용하는 게 좋다고 한다!
API 요청
req.body
req.query
req.params
외부 서비스 응답
환경 변수 (process.env)
form 입력
JSON.parse 결과
내부에서 이미 타입이 보장된 값
로직 중간 단계
무분별하게 사용하지 않게 주의하자 !
Zod는 단순한 validation 라이브러리가 아니라
TypeScript의 타입 안정성을 런타임까지 확장해주는 도구라고 느꼈다.
공부하다 보니 어려운 부분도 있었는데 이것은 다음 심화때 다뤄보도록 하겠다.
출처