Type Alias를 통해 원하는 타입을 직접 정의해서 사용할 수 있다. interface와 유사하나 primitive type, union type, tuple도 값으로 지정할 수 있다는 차이가 있음!
들어올 파라미터와 반환할 결과값 각각의 타입을 지정해 준다.
예를 들어 JS문법으로 작성한 아래와 같은 덧셈 함수는
type Fruits = {
name: string;
emoji: string;
amount: number;
};
기본 type처럼 변수명 뒤에 : 타입명
을 붙여서 선언한다.
const pineapple: Fruits = {
name: 'pineapple',
emoji: '🍍',
amount: 3,
};
다음과 같이 빈 객체를 해당 타입으로 지정하고, 후에 값을 할당할 수도 있음!
const coconut = {} as Fruits;
coconut.name = 'coconut';
coconut.emoji = '🥥';
coconut.amount = 1;
Union Type이란? 하나 이상의 타입 혹은 데이터 집합을 특정한 하나의 타입으로 묶어서 쓸 수 있도록 하는 것!
예를 들어 string과 number 두 타입을 매개변수로 받을 수 있는 함수의 경우, 아래와 같이 string | number
라는 union type으로 지정할 수 있다.
function printCode(x: string | number) {
console.log(`code: ${x}`);
}
타입으로 any
를 지정해도 문자열과 숫자 둘 다 받을 수 있지만, 그렇게 되면 boolean이나 Array 등 다른 모든 데이터 타입까지 허용되어 compile 과정에서 잡을 수 없는 runtime error가 발생할 수 있다.
유니언 타입으로 묶이는 요소로는 타입형식뿐만 아니라 string, number, object 등 데이터도 설정할 수 있음!
type Season = 'spring' | 'summer' | 'fall' | 'winter';
function printSeason(x: Season) {
console.log(x);
}
위처럼 유니언 타입을 정의하고 함수의 인자 타입으로 해당 타입을 지정하면, printSeason의 인자에 빈 문자열(''
)만 입력해도 자동완성으로 'spring', 'summer', 'fall', 'winter'가 뜨게 된다.
Union type으로 묶인 각 타입에 같은 Key값으로 공통 property를 두어 이를 통해 쉽게 구분하는 것!
type Person = Baby | Student | Adult;
type Baby = {
canWalk: boolean;
cantalk: boolean;
}
type Student = {
school: string;
grade: number;
}
type Adult = {
income: number;
isMarried: boolean;
}
만약 위와 같이 Person이라는 이름의 유니언 타입이 있을 때, 이를 인자로 받는 함수에서 각 타입을 구분해 다른 결과를 출력하려면 다음과 같이 특정 key가 존재하는지
를 체크해 주어야 한다.
function Who(name: Person) {
if ('canWalk' in name) {
return 'He/She is too young';
}
if ('school' in name) {
return 'He/She is still young';
}
if ('income' in name) {
return 'He/She is mature';
}
}
const doeun: Adult = {
income: 100000000,
isMarried: false,
};
const bentley: Baby = {
canWalk: true,
canTalk: true,
};
console.log(Who(doeun)); //He/She is mature
console.log(Who(bentley)); //He/She is too young
type Person = Baby | Student | Adult;
type Baby = {
stage: 'baby',
canWalk: boolean;
cantalk: boolean;
}
type Student = {
stage: 'student',
school: string;
grade: number;
}
type Adult = {
stage: 'adult',
income: number;
isMarried: boolean;
}
각 타입에 stage
라는 key값으로 공통 속성을 추가하고, 식별할 수 있도록 각각 'baby', 'student', 'adult'라는 string literal type을 설정했다.
그럼 이 stage를 이용해 각 타입을 구분할 수 있음!
function Who(name: Person) {
switch (name.stage) {
case 'baby':
return 'He/She is too young';
case 'student':
return 'He/She is still young';
case 'adult':
return 'He/She is mature';
}
}
const doeun: Adult = {
stage: 'adult',
income: 100000000,
isMarried: false,
};
const bentley: Baby = {
stage: 'baby',
canWalk: true,
canTalk: true,
};
console.log(Who(doeun)); //He/She is mature
console.log(Who(bentley)); //He/She is too young
물론 여기서도 switch 말고 그냥 if문으로 써도 된다.
여러 타입을 모두 만족하는 하나의 타입을 말한다.
union type이 | 연산자
로 '열거된 여러 타입들 중 하나의 타입'을 의미한다면, intersection type은 & 연산자
로 '열거된 여러 타입을 모두 만족하는(모든 속성을 가진) 새로운 타입'이라고 할 수 있음!
예를 들어 다음처럼 Day, Weather이라는 두 개의 type alias가 있을 때
type Day = {
month: string;
date: number;
dayOfWeek: string;
};
type Weather = {
sunny: boolean;
rainny: boolean;
};
이들로부터 Today라는 새로운 intersection type을 만들 수 있다.
type Today = Day & Weather;
const now: Today = {
month: 'June',
date: 18,
dayOfWeek: 'Fri',
sunny: false,
rainny: true,
};
Today는 Day와 Weather이 지닌 모든 프로퍼티가 포함된 타입이 된다.
연산자를 이용한 타입 정의 | 타입스크립트 핸드북
Discriminated Unions - TypeScript Deep Dive