TypeScript기본 타입과 좁히기

튜플과 readonly 배열

배열처럼 보이지만 길이와 위치 의미를 갖는 tuple, 수정 불가능한 `readonly` 배열과 tuple의 핵심을 정리합니다.

마지막 수정 2026년 3월 22일

기본 패턴

ts
type Point2D = [x: number, y: number];

function move(point: readonly [number, number]) {
  return [point[0] + 1, point[1] + 1] as const;
}

설명

  • 일반 배열은 "같은 타입 원소가 몇 개든 들어갈 수 있는 목록"을 표현합니다. 반면 tuple은 "각 위치마다 의미와 타입이 정해진 고정 길이 배열"을 표현합니다.
  • 그래서 string[]는 단순 문자열 목록이지만, [string, number]는 첫 번째 값은 이름, 두 번째 값은 점수처럼 위치 자체에 의미가 생깁니다.
  • tuple은 반환값을 여러 개 돌려주거나, 좌표, RGB, [state, setState]처럼 순서가 중요한 데이터를 표현할 때 특히 유용합니다.
  • readonly 배열과 readonly tuple은 함수가 입력을 읽기만 하고 수정하지 않는다는 계약을 타입 수준에서 드러냅니다. 이건 단순한 제약이 아니라 함수 의도를 더 명확하게 만드는 도구입니다.
  • 실무에서는 "목록"이면 배열, "위치에 의미가 있으면" tuple, "변경시키지 않을 입력"이면 readonly를 먼저 떠올리면 타입 설계가 훨씬 또렷해집니다.

빠른 정리

표현의미
string[]길이 미정의 문자열 목록
[string, number]위치별 의미가 있는 고정 구조
readonly string[]읽기 전용 배열
readonly [number, number]읽기 전용 tuple
잘 맞는 경우좌표, 페어, 훅 반환값, 상태 묶음

주의할 점

모든 작은 배열을 tuple로 만들면 오히려 읽기 어려워질 수 있습니다. "순서에 의미가 있는가"가 핵심 판단 기준이고, 의미 있는 이름이 필요하면 객체가 더 나을 때도 많습니다.

참고 링크

2 sources