[TypeScript] 타입 별칭과 인덱스 시그니처
타입 별칭 (Type Alias)
저번 포스팅에서 다음과 같이 객체의 타입을 객체 리터럴 타입으로 정의하는 것을 알아보았다.
let user: {
id: number;
name: string;
} = {
id: 1,
name: "정주노",
};
하지만 이렇게 매번 user1, user2 등 user 변수를 선언할 때마다 타입을 객체 리터럴로 프로퍼티 하나하나 작성해야 한다면, 객체를 안쓰고 말 것이다. 이럴 때, 타입 별칭을 활용하면 다음과 같이 변수를 선언하듯 타입을 별도로 정의할 수 있다. 이렇게 만든 타입 별칭은 변수의 타입을 정의할 때 쉽게 사용할 수 있다.
type User = {
id: number;
name: string;
};
let user1: User = {
id: 1,
name: "정주노",
};
let user2: User = {
id: 2,
name: "홍길동",
};
참고로 동일한 스코프에 동일한 이름의 타입 별칭을 중복 선언하는 것은 불가능하다. 이는 마치 변수 선언과 유사하다. 스코프가 다를 경우, 다음과 같이 중복된 이름으로 여러 타입 별칭을 선언해도 상관없다.
type User = {
id: number;
name: string;
nickname: string;
birth: string;
bio: string;
location: string;
};
function test() {
type User = string;
}
인덱스 시그니처 (Index Signature)
인덱스 시그니처는 객체 타입을 유연하게 정의할 수 있도록 돕는 특수한 문법이다.
예를 들어 다음과 같이 다양한 국가들의 영어 코드를 저장하는 객체가 있다고 가정하자.
type CountryCodes = {
Korea: string;
UnitedState: string;
UnitedKingdom: string;
};
let countryCodes: CountryCodes = {
Korea: "ko",
UnitedState: "us",
UnitedKingdom: "uk",
};
만약 이때 countryCodes
객체에 100개의 나라 속성이 추가가 되어야 한다면 객체 뿐만 아니라 CountryCodes
타입도 모두 추가해주어야 하는 번거로움이 생긴다.
이때 인덱스 시그니처를 사용하면 타입의 규칙을 찾아 다음과 같이 한 줄로 간단하게 타입을 정의할 수 있다.
type CountryCodes = {
[key: string]: string;
};
let countryCodes: CountryCodes = {
Korea: "ko",
UnitedState: "us",
UnitedKingdom: "uk",
// (... 약 100개의 국가)
Brazil: "bz",
};
[key: string]: string
은 인덱스 시그니처 문법으로 해당 객체 타입에는 key가 string 타입이고, value가 string 타입인 모든 프로퍼티를 포함한다라는 의미를 갖고있다. 따라서 Korea: "ko"
와 같은 key와 value가 모두 string 타입인 프로퍼티들은 이 타입에 자동으로 포함된다.
추가로, 인덱스 시그니처를 사용함과 동시에 해당 타입이 반드시 포함해야 하는 프로퍼티를 정의할 수 있다. 다음 코드를 살펴보자.
type CountryNumberCodes = {
[key: string]: number;
Korea: number;
};
위 타입은 key가 string 타입이고 value가 number 타입인 모든 프로퍼티를 포함하지만, Korea 프로퍼티를 반드시 포함해야 하며 이 값은 number 타입이어야 함을 나타낸다. 여기서 주의해야 하는 점은 꼭 포함되어야 하는 프로퍼티를 추가로 정의할 때에는 반드시 정의한 시그니처의 타입과 호환되거나 일치해야한다.
type CountryNumberCodes = {
[key: string]: number;
Korea: string; // Error, string타입은 number타입과 호환 X
};
출처
위 포스트는 이정환 님의 인프런: 한 입 크기로 잘라먹는 타입스크립트(TypeScript)를 수강한 뒤 복습 차원에서 저의 생각을 정리 및 추가하여 업로드했음을 알립니다.
댓글남기기