[TypeScript] zod 라이브러리란?

김진영·2023년 6월 23일
7

TypeScript

목록 보기
3/3
post-thumbnail
post-custom-banner

📋 zod 라이브러리란?

zod is a TypeScript-first schema declaration and validation library. -Zod Docs

zod는 공식 문서에 나와있듯이 스키마 선언 및 유효성 검사 라이브러리이다.
지금부터 이 zod에 대해 파헤쳐보자.


📌 1. zod를 사용하는 이유

zod가 필요한 이유는 TypeScript의 한계 때문이다.
TypeScript는 컴파일 시점에서의 타입에러만 잡아낼 수 있고 런타임 단계에서의 타입 에러는 어쩔 수가 없다. 왜냐면 런타임 단계에서 작동되는 것은 JavaScript이기 때문이다.

또 잘 알고있듯이 TypeScript는 number 타입만 입력받도록 강제하는 것은 가능하다.
하지만 원하는 문자열이나 원하는 숫자 범위를 강제하거나 number타입의 정수/실수 구분은 불가능하다.

이러한 TypeScript의 한계 때문에 zod라이브러리를 사용한다.


📌 2. 스키마(schema)

스키마(schema)라는 단어는 형태 , 모양 , 모양 또는 계획 을 의미 하는 그리스어 skhēma 에서 유래했다.
여기서의 스키마란 데이터의 형태 및 구조라고 할 수 있다. 한 남성의 신상 정보에 대해 zod를 통해 스키마를 정의해 보겠다.

import { z } from "zod";

const Man = z.object({
  name: z.string(),
  height: z.number(),
  age: z.number(),
  phoneNum: z.string(),
  homePhoneNum: z.string().optional(),
  isCompletedMilitaryService: z.boolean(),
});

이렇게 zod를 통해 나에대한 정보를 객체 형식으로 나타내보았다.
zod 문법에 대해 배운적이 없더라도 바로 이해할 수 있을 정도로 직관적이다.
이제 이를 통해 유효성 검증을 하는 방법에 대해 알아보자.


📌 3. 유효성 검증

Man.parse({
  name: "김진영",
  height: 180,
  age: 23,
  phoneNum: "01000000000",
  isCompletedMilitaryService: true,
});
// 유효성 검증 통과
//  return {
//  name: "김진영",
//  height: 180,
//  age: 23,
//  phoneNum: "01000000000",
//  isCompletedMilitaryService: true,
//} 

Man.parse({
  name: "아오키지",
  height: 180,
  age: "아이스에이지",
  phoneNum: "01000000000",
  isCompletedMilitaryService: true,
});
// 	유효성 검증 실패
// throws Error

유효성 검증 또한 간단하다. parse를 통해 진행하면 된다.
첫 번째의 경우엔 유효성 검증을 통과했기 때문에 그대로 입력값을 return하고 두 번째같은 경우엔 잘못된 값이 들어왔기 때문에 유효성 검증에 실패하여 Error를 throw한다.

특히 이 Error는 정확히 어떤 부분에서 왜 검증이 실패하였는지에 대한 정보가 들어있기 때문에 매우 유용하다. 위 유효성 검증 실패 예시는 이러한 오류가 뜬다.

[
  {
    "code": "invalid_type",
    "expected": "number",
    "received": "string",
    "path": [
      "age"
    ],
    "message": "Expected number, received string"
  }
]

parse뿐만 아니라 safeParse라는 기능도 있는데, 이 기능은 공식문서를 참고하면 좋을 듯 하다. 공식문서 safeParse 바로가기


📌 4. 타입 추론

또 zod는 스키마를 기준으로 타입을 추론할 수 있다.
이 기능을 통해 타입을 따로 작성할 필요가 없어진다. 아래 예시를 살펴보자.


import { z } from "zod";

const Man = z.object({
  name: z.string(),
  height: z.number(),
  age: z.number(),
  phoneNum: z.string(),
  homePhoneNum: z.string().optional(),
  isCompletedMilitaryService: z.boolean(),
});

type ManType = z.infer<typeof Man>;

const processMan = (man : ManType) => {
  Man.parse(man); // 유효성 검증
  // 사용자 처리 로직
}

이처럼 정의한 스키마로부터 타입을 뽑아내 따로 작성하지 않고도 타입을 정의할 수 있다.


📌 5. 기초 요소

import { z } from "zod";

// primitive values
z.string();
z.number();
z.bigint();
z.boolean();
z.date();
z.symbol();

// empty types
z.undefined();
z.null();
z.void(); // accepts undefined

// catch-all types
// allows any value
z.any();
z.unknown();

// never type
// allows no values
z.never();

참고

https://zod.dev/
https://www.daleseo.com/zod/

post-custom-banner

1개의 댓글

comment-user-thumbnail
2024년 10월 3일

잘 읽었습니다
한번에 이해 될 정도로 명확한 설명 감사합니다.

답글 달기