타입과 인터페이스의 차이점과 비슷한 점 이해
타입스크립트에서 명명된 타입(named type)을 정의하는 방법 두 가지가 있다.
- 방법1. 타입으로 선언
- 방법2. 인터페이스를 사용
// 방법1. 타입으로 선언
type TState = {
name: string;
capital: string;
}
// 방법2. 인터페이스를 사용
interface IState {
name: string;
capital: string;
}
클래스를 사용할 수도 있지만,
클래스는 값으로도 쓰일 수 있는 JS 런타임 개념이다.
인터페이스 선언과 타입 선언의 비슷한 점
1. 명명된 타입은 두 방법으로 정의하든 상태에는 차이가 없다.
IState, TState를 추가 속성과 함께 할당한다면 동일한 오류가 발생한다.
2. 인덱스 시그니처 사용법
type TDict = {
[key: string]: string;
}
interface IDict {
[key: string]: string;
}
3. 함수 타입 정의
type TFn = (x: number) => string;
interface IFn {
(x: number): string;
}
const toStrT: TFn = x => `값: ${x}`;
const toStrI: IFn = x => `값: ${x}`;
4. 두 방법 모두 함수 호출이 가능한 객체이다.
type TFnWithProperties = {
(x: number): number;
prop: string;
}
interface IFnWithProperties {
(x: number): number;
prop: string;
}
5. 제너릭 가능
type TPair<T> = {
first: T;
second: T;
}
interface IPair<T> {
first: T;
second: T;
}
6. 인터페이스는 타입을 확장할 수 있고, 타입은 인터페이스를 확장할 수 있다.
interface IStateWithPop extends TState {
population: number;
}
type TStateWithPop = IState & { population: number; };
클래스에 implements 할 때는 타입과 인터페이스를 둘 다 사용 가능하다.
타입과 인터페이스의 차이점
1. 유니온 타입(O), 유니온 인터페이스(X)
인터페이스는 타입을 확장할 수 있지만, 유니온은 할 수 없다. 단, 유니온 타입을 확장하는게 필요한 경우에는 아래와 같이 할당 가능한 유니온 타입 추가해준다.
type Input = { /* ... */ };
type Output = { /* ... */ };
interface VariableMap {
[name: string]: Input | Output;
}
// 또는
type NamedVariable = (Input | Output) & { name: string };
interface VariableMap {
[name: string]: NamedVariable;
}
2. type 키워드는 일반적으로 interface보다 쓰임새가 많다.
- type 키워드는 유니온이 될 수도 있고
- 매핑된 타입 또는 조건부 타입 같은 고급 기능에 활용되기도 한다.
- 튜플과 배열 타입과 type 키워드를 이용해 더 간결하게 표현할 수 있다.
type Pair = [number, number];
type StringList = string[];
type NamedNums = [string, ...number[]];
3. 인터페이스에만 있는 고유 기능 - 보강(augment)
interface IState {
name: string;
capital: string;
}
interface IState {
population: number;
}
const wyoming: IState = {
name: 'Wyoming',
capital: 'Cheyenne',
population: 500_000,
} // 정상
위 예제처럼 속성을 확장하는 것을 ‘선언 병합’이라고 한다. 선언 병합을 지원하기 위해서는 반드시 interface를 사용해야 하며 표준을 따라야 한다. 타입 선언에는 사용자가 채워야하는 빈틈이 있을 수 있는데, 바로 이 선언 병합이 그렇다.
타입 선언 vs 인터페이스 선언, 어떻게 선택해야할까?
- 복잡한 타입이라면 고민할 것도 없이 타입 선언을 사용하면 된다.
- 타입과 인터페이스, 두 가지 방법으로 모두 표현할 수 있는 간단한 객체 타입이라면 일관성과 보강 관점에서 고려해봐야 한다.
- 일관되게 인터페이스를 사용하는 코드베이스에서 작업하고 있다면 인터페이스를 사용하고
- 일관되게 타입을 사용 중이라면 타입을 사용하면 된다.
- 아직 스타일이 확립되지 않은 프로젝트라면, 향후에 보강의 가능성이 있을지 생각해 봐야 한다.
- 어떤 API에 대한 타입 선언을 작성해야 한다면 인터페이스를 사용하는게 좋다.
- API가 변경될 때 사요앚가 인터페이스를 통해 새로운 필드를 병합할 수 있어 유용하다.
- 그러나 프로젝트 내부적으로 사용되는 타입에 선언 병합이 발생하는 것은 잘못된 설계이다.
출처: 이펙티브 타입스크립트
쿠팡 파트너스 활동을 통해 일정액의 커미션을 제공받을 수 있습니다.