반응형
Enum의 기본 개념과 한계
TypeScript에서 Enum은 관련된 상수들을 그룹화하는 방법을 제공합니다.
// 기본적인 Enum 사용
enum UserRole {
ADMIN = 'ADMIN',
USER = 'USER',
GUEST = 'GUEST'
}
// 사용 예시
function checkAccess(role: UserRole) {
if (role === UserRole.ADMIN) {
return true;
}
return false;
}
하지만 Enum은 몇 가지 중요한 한계가 있습니다:
- Tree-shaking이 불가능
- 컴파일 후 추가적인 런타임 코드 생성
- 번들 크기 증가
Tree-shaking이란?
Tree-shaking은 사용하지 않는 코드를 제거하는 최적화 과정입니다.
// Tree-shaking 전
const utils = {
add: (a: number, b: number) => a + b,
subtract: (a: number, b: number) => a - b,
multiply: (a: number, b: number) => a * b
}
// 실제 사용
utils.add(1, 2)
// Tree-shaking 후 번들에는 add 함수만 포함됨
as const를 사용한 더 나은 해결책
// Enum 대신 const assertion 사용
const UserRole = {
ADMIN: 'ADMIN',
USER: 'USER',
GUEST: 'GUEST'
} as const;
// 타입 추출
type UserRoleType = typeof UserRole[keyof typeof UserRole];
// 사용 예시
function checkAccess(role: UserRoleType) {
if (role === UserRole.ADMIN) {
return true;
}
return false;
}
as const의 장점
더 나은 Tree-shaking
// 일부만 사용해도 필요한 부분만 번들에 포함
import { ADMIN } from './roles';
타입 안전성
const Colors = {
RED: '#ff0000',
GREEN: '#00ff00',
BLUE: '#0000ff'
} as const;
type Color = typeof Colors[keyof typeof Colors];
// 컴파일 타임에 타입 체크
function setColor(color: Color) {
// color는 정확히 '#ff0000' | '#00ff00' | '#0000ff' 타입
}
유연한 확장
const BaseColors = {
RED: '#ff0000',
GREEN: '#00ff00',
BLUE: '#0000ff'
} as const;
const ExtendedColors = {
...BaseColors,
YELLOW: '#ffff00',
PURPLE: '#ff00ff'
} as const;
실제 활용 예시
// API 엔드포인트 정의
const API_ENDPOINTS = {
USER: {
GET: '/api/users',
POST: '/api/users',
PUT: '/api/users/:id',
DELETE: '/api/users/:id'
},
POSTS: {
GET: '/api/posts',
POST: '/api/posts'
}
} as const;
type ApiEndpoint = typeof API_ENDPOINTS;
type UserEndpoints = ApiEndpoint['USER'];
// 타입 안전한 API 호출
async function fetchUser(id: string) {
const url = API_ENDPOINTS.USER.GET.replace(':id', id);
return fetch(url);
}
고급 패턴
유니온 타입 생성
const HttpStatus = {
OK: 200,
CREATED: 201,
BAD_REQUEST: 400,
UNAUTHORIZED: 401,
NOT_FOUND: 404
} as const;
type StatusCode = typeof HttpStatus[keyof typeof HttpStatus];
// type StatusCode = 200 | 201 | 400 | 401 | 404
객체 키 타입 추출
const CONFIG = {
apiUrl: 'https://api.example.com',
timeout: 5000,
retryCount: 3
} as const;
type ConfigKey = keyof typeof CONFIG;
// type ConfigKey = 'apiUrl' | 'timeout' | 'retryCount'
값 타입 매핑
const PERMISSIONS = {
READ: 'read',
WRITE: 'write',
ADMIN: 'admin'
} as const;
type PermissionMap = {
[K in keyof typeof PERMISSIONS]: boolean;
};
// 사용 예시
const userPermissions: PermissionMap = {
READ: true,
WRITE: false,
ADMIN: false
};
이러한 접근 방식은 다음과 같은 이점을 제공합니다:
- 더 작은 번들 크기
- 더 나은 타입 추론
- 런타임 오버헤드 감소
- 더 유연한 코드 구조
Tree-shaking과 타입 안전성을 모두 고려할 때, as const
는 TypeScript에서 상수를 다루는 더 현대적이고 효율적인 방법을 제공합니다. 특히 큰 규모의 애플리케이션에서 번들 크기 최적화가 중요한 경우에 매우 유용합니다.
'TypeScript' 카테고리의 다른 글
React useEffect 의존성 경고 (1) | 2025.02.14 |
---|---|
Nginx 413 Request Entity Too Large 오류 해결 (0) | 2025.02.13 |
[REST API] RESTful API 설계 가이드 (1) | 2025.01.29 |
[HTTP Header 다루기] fetch API의 Headers 인터페이스 (0) | 2025.01.26 |
[JavaScript] 문자열 검색과 비교 (1) | 2025.01.25 |