본문으로 건너뛰기

TypeScript interface와 type 차이 정리

·5 min read

TypeScript에서 데이터 타입을 정의하는 방식은 두 가지다. interfacetype(type alias). 둘 다 객체 모양을 적을 수 있어서 처음엔 같은 도구처럼 보였는데, 막상 코드를 늘려가다 보니 갈라지는 지점이 분명했다. 네 가지 결로 나눠 정리했다.

이미 선언된 타입을 확장하는 방법이 다르다

interfaceextends 키워드로 기존 인터페이스를 확장한다. 다른 객체지향 언어에서 클래스 상속과 같은 모양이라 처음 봤을 때 가장 직관적이었던 부분이다.

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
}

네 갈래를 한 표로

항목interfacetype
확장 방식extends 키워드& (intersection)
동일 이름 재선언자동 병합컴파일 에러
표현 가능한 타입객체 타입만원시·유니온·튜플 등 모두
computed value([key in U])불가가능

객체의 모양을 잡는 데 두 방식이 겹치는 부분은 있어도, 같은 이름을 다시 쓰거나 유니온·매핑 같은 비객체 표현으로 넘어가는 순간 둘은 다른 도구가 된다.