본문으로 건너뛰기

안동민 개발노트

본문 시작

타입 별칭

복잡한 유니온·인터섹션·객체 타입에 재사용 가능한 이름을 붙이고 확장 방식에 따라 type과 interface를 선택합니다.

우리는 객체의 모양을 정의할 때 interface를 사용하는 방법을 배웠습니다.

interface는 주로 객체의 타입을 정의하고, 확장하거나 구현할 때 강력한 도구입니다.

하지만 타입스크립트에는 이 외에도 복잡한 타입을 간결하게 재사용할 수 있도록 돕는 또 다른 강력한 기능이 있는데, 바로 타입 별칭(Type Aliases)입니다.

타입 별칭은 기존에 존재하는 타입에 새로운 이름(별칭)을 부여하는 방법입니다.

이를 통해 복잡한 유니온 타입, 인터섹션 타입, 혹은 객체 리터럴 타입을 더 읽기 쉽고 관리하기 쉬운 이름으로 만들 수 있습니다.

마치 긴 주소를 짧은 별명으로 부르는 것과 같습니다.

HTML 다이어그램: /docs/typescript/ch2/ch2-5/1.html

타입 별칭 정의하기

HTML 다이어그램: /docs/typescript/ch2/ch2-5/2.html

타입 별칭은 type 키워드를 사용하여 정의합니다.

// string 타입에 'Name'이라는 별칭을 부여합니다.
type Name = string;
let myName: Name = "김타입";

// number 타입에 'Age'라는 별칭을 부여합니다.
type Age = number;
let myAge: Age = 30;

// 유니온 타입에 별칭을 부여합니다.
type Id = string | number;
let userId: Id = "user_007";
let adminId: Id = 1004;

// 인터섹션 타입에 별칭을 부여합니다.
type Point = { x: number; y: number };
type ZCoordinate = { z: number };
type ThreeDPoint = Point & ZCoordinate;

let point3d: ThreeDPoint = { x: 10, y: 20, z: 30 };

console.log(myName);     // 김타입
console.log(userId);     // user_007
console.log(point3d.z);  // 30

위 예시에서 볼 수 있듯이, type 키워드 뒤에 별칭으로 사용할 이름을 쓰고, 등호(=) 뒤에 별칭을 부여할 타입을 정의합니다.

이렇게 정의된 별칭은 원래의 타입을 사용하는 것처럼 어디든 사용할 수 있습니다.


객체 타입 정의에 타입 별칭 사용하기

타입 별칭은 특히 객체 타입을 정의할 때 매우 유용합니다.

interface와 유사하게 객체의 모양을 정의할 수 있습니다.

// 'User'라는 타입 별칭으로 객체 타입을 정의합니다.
type User = {
  id: string;
  name: string;
  email?: string; // 선택적 속성
  readonly registrationDate: Date; // 읽기 전용 속성
};

let currentUser: User = {
  id: "u_abc",
  name: "이코딩",
  registrationDate: new Date(),
};

let newUser: User = {
  id: "u_xyz",
  name: "박개발",
  email: "park@example.com",
  registrationDate: new Date("2024-01-01"),
};

console.log(currentUser.name); // 이코딩
// newUser.registrationDate = new Date(); // Error: registrationDate는 읽기 전용입니다.

이전 2장 3절에서 interface로 정의했던 Person과 거의 동일하게 User 타입을 정의했음을 알 수 있습니다.


인터페이스와 타입 별칭의 차이점

타입 별칭과 인터페이스는 객체의 타입을 정의하는 데 모두 사용될 수 있어 비슷하게 느껴질 수 있습니다.

하지만 몇 가지 중요한 차이점이 있습니다.

확장 및 구현 방식
  • 인터페이스: extends 키워드를 사용하여 다른 인터페이스를 확장할 수 있고, 클래스가 implements 키워드를 사용하여 인터페이스를 구현할 수 있습니다. 이는 객체 지향적인 상속과 계약 관계를 명확히 표현할 때 유리합니다.
  • 타입 별칭: extendsimplements 키워드를 직접 사용할 수는 없습니다. 하지만 인터섹션 타입(&)을 사용하여 인터페이스와 유사한 확장 효과를 낼 수 있습니다.
// 인터페이스 확장 (extends)
interface BaseShape {
  color: string;
}
interface Circle extends BaseShape {
  radius: number;
}

// 타입 별칭을 이용한 '확장' (인터섹션 &)
type BaseShapeAlias = {
  color: string;
};
type CircleAlias = BaseShapeAlias & {
  radius: number;
};
재선언 (Declaration Merging)
  • 인터페이스: 동일한 이름으로 여러 번 선언해도 자동으로 병합(Merge)됩니다. 이는 라이브러리에서 기존 타입에 새로운 속성을 추가하는 등의 상황에서 유용합니다.
  • 타입 별칭: 동일한 이름으로 여러 번 선언할 수 없습니다. 즉, 재선언 시 오류가 발생합니다.
// 인터페이스 병합 예시
interface Car {
  brand: string;
}
interface Car { // 동일한 이름으로 다시 선언해도 오류 없음
  model: string;
}
let myCar: Car = { brand: "BMW", model: "X5" }; // brand와 model 모두 가짐

// 타입 별칭 재선언 시 오류
// type Product = { name: string };
// type Product = { price: number }; // Error: Duplicate identifier 'Product'.
원시 타입, 유니온, 튜플 등 정의
  • 타입 별칭: 원시 타입, 유니온, 튜플 등 모든 종류의 타입에 별칭을 부여할 수 있습니다.
  • 인터페이스: 주로 객체의 모양을 정의하는 데 사용되며, 원시 타입이나 유니온, 튜플을 직접적으로 정의할 수는 없습니다. (물론 인터페이스 내부 속성으로는 가능합니다.)
type StringOrNumber = string | number; // 타입 별칭은 유니온 타입에 사용 가능
type PointTuple = [number, number];   // 타입 별칭은 튜플 타입에 사용 가능
// interface MyPrimitive extends string {} // Error: 인터페이스는 원시 타입을 확장할 수 없습니다.

아래 다이어그램은 interfacetype 별칭을 선택할 때 확인할 기준을 프로젝트 적용 관점에서 정리한 것입니다.

HTML 다이어그램: /docs/typescript/ch2/ch2-5/3.html

타입 별칭과 인터페이스는 기능이 겹치는 부분이 많기 때문에 팀 규칙 없이 섞어 쓰면 읽는 사람이 의도를 추측해야 합니다.

아래 다이어그램은 새 타입을 만들 때 먼저 확인할 선택 기준을 정리한 것입니다.

HTML 다이어그램: /docs/typescript/ch2/ch2-5/4.html

언제 무엇을 사용해야 할까?

일반적인 가이드라인은 다음과 같습니다.

  • 객체의 모양(Shape)을 정의하고, 향후 다른 인터페이스가 이를 확장하거나 클래스가 구현해야 할 가능성이 있다면 interface를 사용하는 것이 좋습니다. 특히 라이브러리나 프레임워크처럼 확장성이 중요한 설계에서는 interface가 더 강력한 도구입니다.
  • 원시 타입, 유니온 타입, 튜플 타입 등 객체 이외의 타입을 포함하여 어떤 타입이든 간결하게 별칭을 부여하고 싶을 때는 type 별칭을 사용합니다. interface로는 표현하기 어려운 복잡한 조합의 타입을 정의할 때 유용합니다.

최근 타입스크립트 버전에서는 interfacetype 별칭의 기능적 차이가 많이 줄어들었지만, 위에서 언급한 주요 차이점들은 여전히 유효합니다.

프로젝트의 성격과 팀의 컨벤션에 따라 선택하여 사용할 수 있습니다.


이로써 타입스크립트의 기본 타입들에 대한 학습을 마쳤습니다.

숫자, 문자열, 불리언과 같은 기본 데이터부터 시작하여, 복잡한 객체와 그 형태를 정의하는 인터페이스, 그리고 유연한 타입 조합을 위한 유니온/인터섹션, 마지막으로 타입에 새 이름을 부여하는 타입 별칭까지, 타입스크립트의 견고한 타입 시스템을 위한 핵심 개념들을 살펴보았습니다.


다음 다이어그램은 TypeScript 타입 별칭을 객체, 유니온, 함수 시그니처, 재사용 경계로 나누어 쓰는 기준입니다.

HTML 다이어그램: /docs/typescript/ch2/ch2-5/5.html

다음 다이어그램은 타입 별칭을 언제 쓰고 interface와 어떻게 나눌지 정리한 판단표입니다.

HTML 다이어그램: /docs/typescript/ch2/ch2-5/6.html
HTML 다이어그램: /docs/typescript/ch2/ch2-5/7.html

아래 다이어그램은 type 별칭과 interface를 언제 선택할지 확장성과 표현 범위로 비교합니다.

HTML 다이어그램: /docs/typescript/ch2/ch2-5/8.html