📌 키 포인트
- 한 가지 일관된 스타일을 확립하고, 보강 기법이 필요한가 고려해야 한다.
- interface로는 union 연산자 사용 불가
- 보강이 필요하다면
interface
, 그렇지 않은 일반적인 경우라면type
이 유용하다.- 기존에 작업 중이던 타입이 있다면 컨벤션을 맞춰 따라가는 것도 중요하다.
참고: 예제에서 식별자 이름 앞에 I, T를 붙여 구분하는 것은 현재 안티패턴이다. 이는 c#에서 유래된 것이다.
👉 Hey TypeScript, where’s my I-prefixed interface! by Jonathan Yee
type TState = {
name: string;
capital: string;
}
interface IState {
name: string;
capital: string;
}
// IState, TState 모두 잉여 속성 체크를 통해 에러를 발생시킨다.
const wyoming: TState = {
name: 'Wyoming',
capital: 'Cheyenne',
population: 500_000
// ~~~~~~~~~~~~~~~~~~ Type ... is not assignable to type 'TState'
// Object literal may only specify known properties, and
// 'population' does not exist in type 'TState'
};
대부분의 상황에서는 타입, 인터페이스 둘 모두로 타입 정의를 할 수 있다.
type TDict = { [key: string]: string };
interface IDict {
[key: string]: string;
}
type TFn = (x: number) => string;
interface IFn {
(x: number): string;
}
const toStrT: TFn = x => '' + x; // OK
const toStrI: IFn = x => '' + x; // OK
type TPair<T> = {
first: T;
second: T;
}
interface IPair<T> {
first: T;
second: T;
}
interface IStateWithPop extends TState {
population: number;
}
type TStateWithPop = IState & { population: number; };
const test1:IStateWithPop = {name: 'd'};
// Type '{ name: string; }' is missing the following properties
// from type 'IStateWithPop': population, capitalts(2739)
const test2:TStateWithPop = {name: 'd'};
// Type '{ name: string; }' is not assignable to type 'TStateWithPop'.
// Property 'capital' is missing in type '{ name: string; }' but required in type 'IState' ts(2322)
class StateT implements TState {
name: string = '';
capital: string = '';
}
class StateI implements IState {
name: string = '';
capital: string = '';
}
✍️ implements, extends 차이
- union은 타입만 가능하다 ⭕
type AorB = 'a' | 'b';
type Input = { /* ... */ };
type Output = { /* ... */ };
interface VariableMap {
[name: string]: Input | Output;
}
// 유니온을 활용
type NamedVariable = (Input | Output) & { name: string };
// 튜플, 배열 등 타입 정의
type Pair = [number, number];
type StringList = string[];
type NamedNums = [string, ...number[]];
- 보강은 인터페이스만 가능하다 ⭕
interface IState {
name: string;
capital: string;
}
interface IState {
population: number;
}
const wyoming: IState = {
name: 'Wyoming',
capital: 'Cheyenne',
population: 500_000
}; // OK
- 인터페이스는 보강 기법을 사용할 수 있지만 union 등 복잡한 연산자를 사용할 수 없다.
- 기존에 작성되던 타입 정의 방법을 따르되 정의 목적에 따라 통일성이 있어야 한다.
- 새로 정의할 수 있다면 보강 기법이 필요한 곳엔 인터페이스, 그 외엔 타입으로 통일하자.