기본 타입에는 string, boolean, number, array, tuple, enum이 있다.
하지만 우리가 다루는 타입은 이게 다가 아니다. 추가적으로 우리는 type aliases(타입 별칭)라는 기능을 통해 위 타입 이외의 타입을 다루게 될 수도 있다.
이는 쉽게 말해, type들에게 닉네임을 붙여주는 일이라고 생각하면 된다. 즉, 새로운 타입을 정의하는 느낌이 아니라 그저 우리가 만든 어떤 타입에게 괜찮은 이름 하나를 붙여주는 것이라고 생각하면 된다.
type MyNumber = number;
type User = {
id: number;
name: string;
email: string;
}
{
type CustomString = string;
const str: CustomString = '';
// ❌
interface CustomStringByInterface = string;
}
타입은 원시 타입(symbol, boolean, string, number, bigint, etc.)을 정의할 수 있다.
반면에 인터페이스는 불가능하다. 타입은 새로운 타입을 만드는 것이 아니기 때문에 type alias로 불린다. 반면에 인터페이스는 항상 새로운 타입을 생성한다.
{
type Fruit = 'apple' | 'lemon';
type Vegetable = 'potato' | 'tomato';
// 'apple' | 'lemon' | 'potato' | 'tomato'
type Food = Fruit | Vegetable;
const apple: Food = 'apple';
}
유니온 타입은 타입만 사용 가능하다.
<interface를 사용하는 경우>
반면, interface는 number와 같은 원시 타입을 직접적으로 정의하는 용도로 사용될 수 없다.
인터페이스와 타입 모두 객체 타입이나 함수 타입을 선언할 수 있다. 하지만 인터페이스의 경우, 같은 인터페이스를 여러번 선언 가능하다. 그리고 그들은 자동으로 병합된다. 반면에 타입은 병합되지 않고 유니크 해야 한다.
타입을 사용해야 하는 경우
- 원시 타입을 정의할 경우
- 튜플 타입을 정의할 경우
- 함수 타입을 정의할 경우
- 유니온 타입을 정의할 경우
- 매핑된 타입을 정의할 경우
인터페이스를 사용해야 하는 경우- 선언 병합(자동 병합)의 이점을 활용해야 하는 경우
- 객체 타입을 정의하거나, 타입을 사용할 필요가 없을 경우
- API에 대한 타입을 정의해야 하는 경우
- type은 같은 이름으로 확장할 수 없지만, interface는 같은 이름으로의 확장이 가능하다.
(type은 같은 이름으로 확장하면 오류가 난다.)- type은 number, string, array 와 같은 자료형에 대한 타입도 정의할 수 있지만, interface는 오로지 object 타입만 정의할 수 있다.
- type은 union type, intersection type으로 정의할 수 있지만, interface는 불가능하다.