본문 바로가기
카테캠/2단계

[7/14]zod 라이브러리

by 쪼꼬에몽 2025. 7. 14.

타입스크립트 친화적인 스키마 기반 유효성 검사 라이브러리

zod 스키마 정의

import { z } from 'zod';

export const loginSchema = z.object({
	email: z.string().email({ message: '유효한 이메일을 입력해주세요.' }),
    password: z.string().min(6, { message: '비밀번호는 최소 6자 이상이어야 합니다.' })
});

z.object({...}) 스키마 정의 시작

z.string().email() 문자열 & 이메일 형식 검사

min(n) / max(n) 길이 제한

폼 설정

import { useForm } from 'react-hook-form';
import { zooResolver } from '@hookform/resolvers/zod';
import { loginSchema } from '@/schema/loginSchema';

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

zodResolver RHF와 스키마 연결

JSX에서 사용

<form onSubmit={ handleSubmit(data => console.log(data))}>
	<input {...register('email')} placeholder="이메일" />
    {errors.email && <p>{errors.email.message}</p>}
</form>

체크박스 배열

const schema = z.object({
	items: z.array(z.string()).min(1, '하나 이상 선택해주세요.'),
})
{options.map(item => (
	<label key={item}>
    	<input
        	type='checkbox'
            value={item}
            {...register('items')}
        />
        {item}
    </label>
))}

zod props

타입 메서드 설명
z.string() .min(n), .max(n), .email(), .regex() 문자열 검사
z.number() .min(n), .max(n), .int(), .positive() 숫자 검사
z.boolean() - 불리언 검사
z.array() .length(n), .min(n), .max(n) 배열 검사
z.enum() z.enum(['a', 'b']) enum 값 제한
z.union() z.union([z.string(), z.number()]) 여러 타입 중 하나 허용
z.object() 필드 정의 객체 검사
z.optional() 필수 아님 옵션 필드 지정
z.nullable() null 허용 null 허용 필드
z.literal() 특정 값만 허용 z.literal('admin')

유효성 메시지 커스터마이징

const schema = z.object({
	email: z.string()
    	.email({ message: '올바른 이메일 형식이 아닙니다.' }),
    password: z.string()
    	.min(6, { message: '비밀번호는 최소 6자리 이상입니다.' }),
});

 

객체 구조 유효성 검사

const schema = z.object({
	user: z.object({
    	name: z.string(),
        phone: z.string().regex(/^010\d{8}$/),
    }),
});

 

배열 유효성 검사

const schema = z.object({
	items: z.array(z.string()).min(1, { message: '하나 이상 선택해주세요.' }),
});

 

조건부 검사(.refine)

const schema = z.object({
	password: z.string().min(6),
    confrimPassword: z.string(),
}).refine(data => data.password === data.confirmPassword, {
	path: ['confirmPassword'],
    message: '비밀번호가 일치하지 않습니다.',
});

 

optional / nullable

.optional() : 값이 없어도 통과됨 (undefined 허용)

.nullable() : null 허용됨

.nullish() : null 또는 undefined 허용

z.string().optional(); // string | undefined
z.string().nullable(); // string | null
z.string().nullish(); // string | null | undefined

 

react-hook-form과 연동

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

const schema = z.object({
	email: z.string().email(),
    password: z.string().min(6),
});

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

 

기본값 설정 (.default())

z.string().default('기본값')

 

커스텀 유효성 검사 (refine())

z.string().refine(val => val.startsWith('A'), {
	message: 'A로 시작해야 합니다.',
});

 

사용자 정의 에러 던지기 (safeParse())

const result = schema.safeParse(data);
if (!result.success) {
	console.log(result.error.format());
}

 

 

 

 

'카테캠 > 2단계' 카테고리의 다른 글

[7/16] Promise  (0) 2025.07.16
[7/15] 동기식 vs 비동기식  (3) 2025.07.16
[7/10] useFormContext  (1) 2025.07.14
[7/10] 고차 함수  (0) 2025.07.10
[7/9] 중복 전화번호 검사, 모달 취소 시 되돌리기  (1) 2025.07.09