TypeScript interface와 type 차이 정리
TypeScript에서 데이터 타입을 정의하는 방식은 두 가지다. interface와 type(type alias). 둘 다 객체 모양을 적을 수 있어서 처음엔 같은 도구처럼 보였는데, 막상 코드를 늘려가다 보니 갈라지는 지점이 분명했다. 네 가지 결로 나눠 정리했다.
이미 선언된 타입을 확장하는 방법이 다르다
interface는 extends 키워드로 기존 인터페이스를 확장한다. 다른 객체지향 언어에서 클래스 상속과 같은 모양이라 처음 봤을 때 가장 직관적이었던 부분이다.
interface PersonInterface {
firstName: string;
lastName: string;
}
interface ResidentInterface extends PersonInterface {
location: string;
}
// 결과적으로 ResidentInterface는 아래와 같다
// interface ResidentInterface {
// firstName: string;
// lastName: string;
// location: string;
// }type은 & 연산자(intersection type, 두 타입을 모두 만족해야 하는 타입을 만든다)로 확장한다. 키워드 대신 연산자라는 점만 다르고, 결과적으로 만들어지는 모양은 같다.
type PersonInterface = {
firstName: string;
lastName: string;
}
type ResidentInterface = PersonInterface & {
location: string;
}
// 결과적으로 ResidentInterface는 아래와 같다
// type ResidentInterface = {
// firstName: string;
// lastName: string;
// location: string;
// }같은 이름으로 다시 선언했을 때의 동작이 갈린다
interface는 동일한 이름으로 여러 번 선언해도 컴파일 시점에 자동으로 병합된다(declaration merging). 에러가 나지 않고 두 선언이 합쳐진 하나의 인터페이스로 동작한다.
interface Fruits {
name: string;
}
interface Fruits {
color: string;
}
// 컴파일 시점에 아래와 동일하게 병합된다
// interface Fruits {
// name: string;
// color: string;
// }type은 그렇지 않다. 같은 이름으로 두 번 선언하면 컴파일 단계에서 바로 막힌다.
type Fruits = {
name: string;
}
type Fruits = {
color: string;
}
// Error: Duplicate identifier 'Fruits'표현할 수 있는 타입의 폭이 다르다
interface는 객체 타입을 정의할 때만 쓸 수 있다. type alias는 원시 타입, 유니온, 튜플 같은 비객체 타입까지 표현할 수 있지만 interface는 그렇지 못하다.
type ID = string | number;
type Tuple = [string, number];
type Status = "idle" | "loading" | "done";이런 식의 정의는 interface로는 만들 수 없다.
computed value(계산된 키)는 type만 받아준다
객체 타입의 키를 다른 유니온 타입으로부터 매핑하는 경우, type은 [key in 유니온] 문법으로 표현이 가능하지만 interface는 같은 자리에서 컴파일 에러가 난다.
type names = 'firstName' | 'lastName'
type NameTypes = {
[key in names]: string
}
const yc: NameTypes = { firstName: 'hi', lastName: 'yc' }
interface NameInterface {
// error: A mapped type may not declare properties or methods.
[key in names]: string
}네 갈래를 한 표로
| 항목 | interface | type |
|---|---|---|
| 확장 방식 | extends 키워드 | & (intersection) |
| 동일 이름 재선언 | 자동 병합 | 컴파일 에러 |
| 표현 가능한 타입 | 객체 타입만 | 원시·유니온·튜플 등 모두 |
computed value([key in U]) | 불가 | 가능 |
객체의 모양을 잡는 데 두 방식이 겹치는 부분은 있어도, 같은 이름을 다시 쓰거나 유니온·매핑 같은 비객체 표현으로 넘어가는 순간 둘은 다른 도구가 된다.