Ch 02. 배열, 튜플, 열거형
배열의 두 가지 문법, 변경 불가 배열, 고정 구조 튜플, 그리고 열거형의 세 가지 선택지를 다룹니다.
배열 타입
두 가지 문법은 완전히 동일합니다. 팀 컨벤션에 맞춰 하나로 통일하세요.
// 파일: src/arrays.ts// 문법 1: 타입[]const names: string[] = ["Alice", "Bob"];// 문법 2: Array<타입>const scores: Array<number> = [90, 85, 78];// 중첩 배열const matrix: number[][] = [[1, 2], [3, 4]];// 혼합 타입 — 유니온 사용const mixed: (string | number)[] = ["Alice", 30, "Bob", 25];
readonly 배열
변경을 막아야 할 때는 readonly를 붙입니다.
// 파일: src/readonly-array.tsconst DAYS: readonly string[] = ["Mon", "Tue", "Wed", "Thu", "Fri"];DAYS.push("Sat"); // Error: Property 'push' does not exist on type 'readonly string[]'DAYS[0] = "Sunday"; // Error: Index signature in type 'readonly string[]' only permits reading// ReadonlyArray<T>도 동일const CODES: ReadonlyArray<number> = [200, 201, 404, 500];
상수 배열, 함수 매개변수로 받은 배열을 변경하지 않겠다는 의도를 명시할 때 씁니다.
튜플
길이와 각 위치의 타입이 고정된 배열입니다.
// 파일: src/tuples.ts// 기본 튜플type Point = [number, number];const origin: Point = [0, 0];const p: Point = [3, 4];// 레이블 튜플 (TypeScript 4.0+) — 가독성 향상type RGB = [red: number, green: number, blue: number];const white: RGB = [255, 255, 255];// 구조 분해와 함께 사용const [x, y] = p;console.log(x, y); // 3 4// 선택적 요소type Flexible = [string, number, boolean?];const a: Flexible = ["Alice", 30];const b: Flexible = ["Bob", 25, true];
실무 패턴 — 함수 다중 반환값
// 파일: src/tuple-return.ts// React의 useState 방식function useToggle(initial: boolean): [boolean, () => void] { let state = initial; const toggle = () => { state = !state; }; return [state, toggle];}const [isOpen, toggleOpen] = useToggle(false);
튜플은 관련 값의 쌍을 반환할 때 객체보다 간결합니다. 단, 3개 이상이면 객체가 더 명확합니다.
enum
// 파일: src/enum.tsenum Direction { Up, // 0 Down, // 1 Left, // 2 Right, // 3}function move(dir: Direction): void { if (dir === Direction.Up) { console.log("moving up"); }}move(Direction.Up);// 문자열 enum — 디버깅 시 값이 의미 있음enum Status { Pending = "PENDING", Active = "ACTIVE", Closed = "CLOSED",}const s: Status = Status.Active;console.log(s); // "ACTIVE"
일반 enum은 컴파일 후 객체 코드가 생성됩니다.
const enum
런타임 객체 없이 컴파일 시점에 인라인됩니다.
// 파일: src/const-enum.tsconst enum HttpMethod { Get = "GET", Post = "POST", Put = "PUT", Delete = "DELETE",}function request(url: string, method: HttpMethod) { fetch(url, { method });}request("/api/users", HttpMethod.Get);// 컴파일 결과: request("/api/users", "GET");// HttpMethod 객체 자체는 번들에 포함되지 않음
번들 크기를 줄이려면 const enum이 유리합니다. 단, 외부 패키지에서 사용하는 경우에는 문제가 생길 수 있으므로 라이브러리 코드에는 피하세요.
리터럴 유니온 — enum 대안
실무에서 enum 대신 많이 쓰입니다.
// 파일: src/literal-union.tstype Direction = "up" | "down" | "left" | "right";type HttpStatus = 200 | 201 | 400 | 404 | 500;function move(dir: Direction): void { console.log(`moving ${dir}`);}move("up"); // OKmove("fly"); // Error: Argument of type '"fly"' is not assignable to type 'Direction'
enum vs const enum vs 리터럴 유니온 비교
| 방식 | 런타임 존재 | 역방향 조회 | 트리쉐이킹 | 권장 상황 |
|---|---|---|---|---|
enum |
O | O | X | 레거시 코드, 역방향 조회 필요 |
const enum |
X | X | O | 성능 민감, 내부 코드 |
| 리터럴 유니온 | X | X | O | 신규 코드 기본 선택 |
신규 코드라면 리터럴 유니온을 기본으로 선택하세요. enum은 역방향 조회(Direction[0] === "Up")가 필요할 때만 씁니다.