타입스크립트로 프로젝트를 진행하는데 타입을 선언하는 코드가 개발자마다 자유롭게 혼용되어 사용하고 있다. 타입스크립트에서 Type, Interface 는 비슷한 점이 많지만 이 둘의 차이와 한계점이 있으므로 이에 대해 정리하려고 한다.
타입으로만 원시 타입(boolean, string, number, etc...)을 정의할 수 있다.
type Age = number;
type Name = string;
const name: Name = '타입';
타입으로만 유니온 타입을 정의할 수 있다.
type City = 'seoul' | 'busan';
const apple: City = 'seoul';
타입으로만 튜플 타입을 정의할 수 있다.
type Person = [name: string, age: number];
const person: Person = ['이름', 10];
// 객체 타입
type Person = {
name: string;
age: number;
};
// 함수 타입
type AddFunc = (a: number, b: number) => number;
const add: AddFunc = (a, b) => a + b;
& 를 사용하여 병합이 가능하다.
// 🙅: 타입 이름이 중복됨
type Person = {
name: string;
};
type Person = {
age: number;
};
// 🙆♀️: 사용 가능
type Address = {
city: string;
postalCode: string;
};
type ExtendedPerson = Person & Address;
매핑된 객체 타입은 타입으로만 정의될 수 있고, in, keyof 를 사용할 수 있다.
type Person = {
name: string;
age: number;
};
type PartialPerson = {
[K in keyof Person]?: Person[K];
};
// 예시
const partialPerson: PartialPerson = {};
partialPerson.name = "John";
partialPerson.age = 25;
Interface에서는 정의할 수 없다.
// 🙅
interface Name = string;
// 객체 타입
interface Person {
name: string;
age: number;
address?: string; // optional
}
const person: Person = {
name: "벨로그",
age: 10,
address: "서울시....", // optional 속성 사용 가능
};
// 함수 타입
interface Calc {
(a: number, b: number): number;
}
const add: Calc = (a, b) => a + b;
// extends
interface Person {
name: string;
age: number;
}
interface Job extends Person {
role: string;
}
const personInfo: Job = {
name: "John",
age: 30,
role: "Developer",
};
// 자동병합 가능
interface Person {
name: string;
age: number;
}
interface Person {
role: string;
}
const personInfo: Person = {
name: "John",
age: 30,
role: "Developer",
};
타입은 인터페이스의 거의 모든 기능을 커버한다. 그러나 인터페이스는 항상 확장 가능하고, 타입은 그렇지 않다. 그러므로 경우에 따라서 선택하여 사용해야 한다.
추가적으로 타입스크립트 공식 문서 에 따르면
Differences Between Type Aliases and Interfaces
Type aliases and interfaces are very similar, and in many cases you can choose between them freely. Almost all features of an interface are available in type, the key distinction is that a type cannot be re-opened to add new properties vs an interface which is always extendable.
(Type Aliases과Interfaces의 차이점은 매우 유사하며, 대부분의 경우 두 가지를 자유롭게 선택할 수 있습니다. 인터페이스의 거의 모든 기능은 타입에서도 사용할 수 있으며, 주요한 차이점은 타입은 새로운 속성을 추가하여 다시 열 수 없다는 것입니다. 반면 인터페이스는 항상 확장 가능.)
For the most part, you can choose based on personal preference, and TypeScript will tell you if it needs something to be the other kind of declaration. If you would like a heuristic, use interface until you need to use features from type.
(문제가 생기면 컴파일러가 알려줄 테니까 개인 취향에 따라 선택하고, TypeScript는 필요한 경우 다른 종류의 선언이 필요하다고 알려줄 테니까 개인의 취향에 따라 선택하라고 한다. 휴리스틱(규칙적인 경험에 기반한 지침)이 필요하다면, 타입의 기능이 필요할 때까지는Interface를 사용.)