해당 게시글은
강의 사이트, 인프런에서 이정환님이 진행하시는
'한 입 크기로 잘라먹는 타입스크립트' 를
들어보며 블로그를 작성하려고 합니다.
다음 게시글 내용은 해당 강의에 핸드북의 내용으로
출처는 다음과 같습니다.
https://ts.winterlood.com/7250edd7-a3fd-4662-b756-f11f927c73f2
타입스크립트를 소개합니다 - 타입스크립트 개론
한 입 크기로 잘라먹는 타입스크립트
ts.winterlood.com
이번 글에서는
타입 정의를 마치 변수처럼 하게 해주는
"타입 별칭" 이라는 문법과 함께
이전 시간에 배운 객체 타입을 좀 더 유연하게 정의하도록 도와주는
"인덱스 시그니처" 라는 문법도 배워보았습니다.
이번 실습은 chapter4.ts 에서 진행합니다.
타입 별칭(Type Alias)
타입 별칭을 이용하면,
다음과 같이 변수를 선언하듯 타입을 정의할 수 있습니다.
// 타입 별칭
type User = {
id: number;
name: string;
nickname: string;
birth: string;
bio: string;
location: string;
};
...
'type 타입_이름 = 타입' 형태로 정의합니다.
위 코드는 타입 이름으로는 User,
타입으로는 여러 개의 프로퍼티가 있는 객체 타입을 정의했습니다.
이렇게 만든 타입 별칭은 다음과 같이
변수의 타입을 정의할 때 타입 주석과 함께 이용할 수 있습니다.
type User = {
id: number;
name: string;
nickname: string;
birth: string;
bio: string;
location: string;
};
let user: User = {
id: 1,
name: "이정환",
nickname: "winterlood",
birth: "1997.01.07",
bio: "안녕하세요",
location: "부천시",
};
let user2: User = {
id: 2,
name: "홍길동",
nickname: "winterlood",
birth: "1997.01.07",
bio: "안녕하세요",
location: "부천시",
};
참고로 동일한 스코프에 동일한 이름의 타입 별칭을 선언하는 것은 불가능합니다.
마치 변수 선언과 유사합니다.
type User = {
id: number;
name: string;
nickname: string;
birth: string;
bio: string;
location: string;
};
type User = {} //불가능
그러나 스코프가 다르다면,
다음과 같이 중복된 이름으로 여러 개의 별칭을 선언해도 상관없습니다.
type User = {
id: number;
name: string;
nickname: string;
birth: string;
bio: string;
location: string;
};
function test() {
type User = string;
}
test 함수 내부에서는 User 가 string 타입이 되고,
test 함수 바깥에서는 User 가 객체 차입이 됩니다.
이전 시간에 타입 관련 문법은 컴파일과 함께 모두 사라진다고 살펴보았습니다.
타입 별칭 또한 타입 관련 문법이기 때문에
컴파일 결과 사라집니다.
다음은 chapter4.ts 를 tsc 로 컴파일 한 결과입니다.
let user = {
id: 1,
name: "이정환",
nickname: "winterlood",
birth: "1997.01.07",
bio: "안녕하세요",
location: "부천시",
};
let user2 = {
id: 2,
name: "홍길동",
nickname: "winterlood",
birth: "1997.01.07",
bio: "안녕하세요",
location: "부천시",
};
export {};
인덱스 시그니처(Index Signature)
인덱스 시그니처는
객체 타입을 유연하게 정의할 수 있도록 돕는 특수한 문법입니다.
다양한 국가들의 영어 코드를 저장하는 객체가 하나 있다고 가정합니다.
type CountryCodes = {
Korea: string;
UnitedState: string;
UnitedKingdom: string;
};
let countryCodes: CountryCodes = {
Korea: "ko",
UnitedState: "us",
UnitedKingdom: "uk",
};
만약 이때,
countryCodes 에 100개의 프로퍼티(국가 코드)가 추가되어야 한다면,
타입 정의에도 각 프로퍼티를 모두 정의해주어야 하기 때문에 매우 불편할 겁니다.
type CountryCodes = {
Korea: string;
UnitedState: string;
UnitedKingdom: string;
// (... 약 100개의 국가)
Brazil : string
};
let countryCodes: CountryCodes = {
Korea: "ko",
UnitedState: "us",
UnitedKingdom: "uk",
// (... 약 100개의 국가)
Brazil : 'bz'
};
바로 이럴 때, 인덱스 시그니처를 이용하면
다음과 같이 간단하게 타입을 정의할 수 있습니다.
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" 나 Brazil: "bz" 처럼
key 와 value 가 모두 string 타입인 이런 프로퍼티들이
굳이 일일히 타입들을 직접 명시하지 않아도
타입에 자동으로 포함됩니다.
만약 국가 코드를 숫자로 보관하는 객체가 하나 더 필요하다고 하면,
그때의 타입은 다음과 같이 정의하면 됩니다.
type CountryNumberCodes = {
[key: string]: number;
};
또 이때 반드시 포함해야 하는 프로퍼티가 있다면
다음과 같이 직접 명시해도 됩니다.
type CountryNumberCodes = {
[key: string]: number;
Korea: number;
};
한 가지 주의할 점은
인덱스 시그니처를 사용하면서 동시에 추가적인 프로퍼티를 또 정의할 때에는
인덱스 시그니처의 value 타입과 직접 추가한 프로퍼티의 value 타입이
호환되거나 일치해야 합니다.
따라서 다음과 같이 서로 호환되지 않는 타입으로 설정하면
오류가 발생합니다.
type CountryNumberCodes = {
[key: string]: number;
Korea: string; // 오류!
};
string 타입은 number 타입과 호환되지 않기 때문입니다.
호환에 대해서는 3섹션에서 자세히 다룹니다.
'TypeScript > 한 입 크기로 잘라먹는 타입스크립트' 카테고리의 다른 글
[타입스크립트 기본] any 와 unknown (0) | 2023.07.06 |
---|---|
[타입스크립트 기본] 열거형 타입 (0) | 2023.07.06 |
[타입스크립트 기본] 객체 (0) | 2023.07.06 |
[타입스크립트 기본] 배열과 튜플 (0) | 2023.07.05 |
[타입스크립트의 기본] 기본타입이란? (0) | 2023.07.05 |