[TYPESCRIPT] 리터럴 타입(Literal Type) - 값 자체가 타입이 되는 TypeScript의 정밀한 타입 시스템

TypeScript는 때때로 “값 그 자체를 타입으로 사용하는” 매우 특별한 타입 시스템을 제공합니다. 이를 리터럴 타입(Literal Type)이라고 하며, 정확한 값만 허용해야 하는 상황에서 강력한 타입 안정성을 보장합니다. 일반적인 string, number 타입보다 훨씬 세밀하게 제어할 수 있기 때문에 상태값, 모드 값, API 응답 타입 등을 정의할 때 자주 사용됩니다.

 

리터럴 타입이란?

리터럴 타입은 “정확히 그 값만 허용하는 타입”입니다. 예를 들어 "red"라는 문자열만 허용하는 타입을 정의할 수 있습니다.

let color: "red";

color = "red";     // 가능
color = "blue";    // 오류

즉, 리터럴 타입은 값이 한정되어 있을 때 특히 유용합니다.

 

문자열 리터럴 타입

가장 많이 사용되는 리터럴 타입은 문자열입니다.

type Direction = "up" | "down" | "left" | "right";

function move(dir: Direction) {
  console.log(`Moving ${dir}`);
}

move("up");     // ✔
move("right");  // ✔
move("back");   // 오류

이는 “허용 가능한 값 목록”을 명확하게 정의하는 방법입니다.

 

숫자 리터럴 타입

숫자도 리터럴 타입으로 지정할 수 있습니다.

type StatusCode = 200 | 404 | 500;

let code: StatusCode;

code = 200;  // ✔
code = 201;  // 오류

API 상태 코드, 고정된 포트 번호, 특정 환경 코드 등을 표현할 때 실무에서 자주 사용됩니다.

 

boolean 리터럴 타입

boolean도 true 또는 false 자체가 타입이 될 수 있습니다.

let isEnabled: true;

isEnabled = true;  // ✔
isEnabled = false; // 오류

상태 값이 특정 boolean 값으로만 제한되어야 할 때 유용합니다.

 

const 선언과 리터럴 타입

const로 선언된 변수는 기본적으로 리터럴 타입으로 추론됩니다.

const level = "info";
// level: "info" 타입으로 추론됨

let mode = "info";
// mode: string 타입으로 추론됨

이는 상수 값이 타입으로 굳어지는 중요한 특징으로, 상태 관리 및 이벤트 타입 모델링에서 큰 장점을 제공합니다.

 

리터럴 타입과 유니온 타입 결합

리터럴 타입은 단독으로도 유용하지만, 유니온 타입과 함께 사용될 때 가장 강력해집니다.

type LogLevel = "debug" | "info" | "warn" | "error";

function log(level: LogLevel, message: string) {
  console.log(`[${level}] ${message}`);
}

이 패턴은 실제 프로젝트에서 가장 많이 사용됩니다.

 

리터럴 타입과 태그드 유니온(Discriminated Union)

리터럴 타입은 “태그(discriminator)” 역할을 하여, 복잡한 유니온 타입 모델을 안전하게 좁히는 데 필수적인 요소입니다.

type Shape =
  | { type: "circle"; radius: number }
  | { type: "square"; size: number };

function getArea(shape: Shape) {
  switch (shape.type) {
    case "circle":
      return Math.PI * shape.radius ** 2;
    case "square":
      return shape.size ** 2;
  }
}

리터럴 타입 덕분에 타입 구분이 명확해지고, 타입 좁히기(Discriminated Union)가 자연스럽게 작동합니다.

 

실무 활용 사례

리터럴 타입은 실제 개발에서 매우 자주 등장합니다.

  • 상태 관리: "idle" | "loading" | "success" | "error"
  • API 응답 코드: 200 | 400 | 404 | 500
  • 로그 레벨: "info" | "debug" | "warn"
  • 권한(Role): "admin" | "user" | "guest"
  • UI 모드: "light" | "dark"
  • HTTP Method: "GET" | "POST" | "PUT" | "DELETE"

즉, “정해진 값만 허용해야 하는 모든 상황”에서 리터럴 타입이 쓰입니다.

 


 

리터럴 타입은 TypeScript의 타입 시스템을 더욱 정밀하고 안전하게 만들어주는 강력한 도구입니다. 특히 유니온 타입, 상태 모델링, 태그드 유니온과 함께 사용하면 런타임 오류를 상당히 줄이면서도 코드의 가독성과 안정성을 크게 높일 수 있습니다.

  • 리터럴 타입 = 값 자체를 타입으로 제한
  • const 변수는 기본적으로 리터럴 타입으로 추론됨
  • 유니온과 결합할 때 가장 강력