아이템13. type과 interface 차이점 알기

2024. 12. 29. 14:16·Backend/TypeScript

타입스크립트에서 named type을 정의하는 방법은 두 가지가 있습니다. 대부분의 경우에는 타입을 사용해도 되고 인터페이스를 사용해도 됩니다. 그러나 타입과 인터페이스 사이에 존재하는 차이를 분명하게 알고, 같은 상황에서는 동일한 방ㅂ버으로 명명된 타입을 정의해 일관성을 유지해야 합니다. 

type TState = {
    name: string;
    capital: string;
}

interface IState {
    name: string;
    capital: string;
}

 

type과 interface의 비슷한 점

1. 인덱스 시그니처는 인터페이스와 타입에서 모두 사용할 수 있다.

type TDict = { [key:string]: string};
interface IDict {
    [key:string]: string;
}

 

 

2. 함수 타입은 인터페이스와 타입으로 정의 가능하다.

type TFunction = (x: string) => string;
interface IFunction {
    (x: string): string;
}

const toStrType: TFunction = x => '@' + x;
console.log(toStrType("hello"));

const toStrInterface: IFunction = x => '@' + x;
console.log(toStrInterface("hello"));

 

 

3. Generic 사용이 둘 다 가능하다. 

type TPair<T> = {
    x: T;
    y: T;
}
const numberTPair: TPair<number> = {
    x:10,
    y:20,
}
console.log(numberTPair.x + " " + numberTPair.y);


interface IPair<T> {
    x: T;
    y: T;
}
const numberIPair: IPair<number> = {
    x:20,
    y:30,
}
console.log(numberIPair.x + " " + numberIPair.y);

 

 

4. 인터페이스는 타입을 확장할 수 있고, 타입은 인터페이스를 확장할 수 있다.

여기서 주의할 점은 인터페이스는 유니온 타입 같은 복잡한 타입을 확장하지는 못한다는 것입니다. 복잡한 타입을 확장하려면 type과 &를 사용해야 합니다. 

type TState = {
    name: string;
    capital: string;
}

interface IState {
    name: string;
    capital: string;
}

// 두 코드는 동일한 기능을 합니다. 
type TStateWithPop = IState & { population: number};

interface IStateWithPop extends TState {
    population: number;
}

 

 

5. 클래스를 구현(implements)할 때는, 타입과 인터페이스 둘 다 가능하다.

type TState = {
    name: string;
    capital: string;
}

interface IState {
    name: string;
    capital: string;
}

class StateT implements TState {
    name: string = "";
    capital: string = "";
}

class StateI implements IState {
    name: string = "";
    capital: string = "";
}

 

 

 

type과 interface의 다른 점

1. 유니온 타입은 있지만, 유니온 인터페이스는 없다.

인터페이스는 타입을 확장할 수 있지만, 유니온은 할 수 없습니다. 그런데 유니온 타입을 확장하는 게 필요할 때가 있습니다. 아래와 같은 예시를 보면, 유니온 타입의 장점이 확연하게 드러납니다. 

type RequestState = 'idle' | 'loading' | 'success' | 'error';

type RequestData<T> = {
    state: RequestState;
    data?: T;
    error?: string;
}

interface User {
    id: number;
    name: string;
}

const userRequest: RequestData<User> = {
    state: 'success',
    data: {id:1, name: "John"}
};

const failedRequest: RequestData<User> = {
    state: 'error',
    error: "Failed to fetch user"
}

 

 

인터페이스로 구현해면 되지 않냐구요? 인터페이스로 구현하고, 타입을 사용했을 경우와 비교해보도록 하겠습니다. 한 눈에 봐도 복잡한 코드임을 알 수 있습니다. 이런 경우에는 타입스크립트의 type을 최대한 활용하는 것이 적절해 보입니다.

interface RequestStateMap {
    readonly IDLE: 'idle';
    readonly LOADING: 'loading';
    readonly SUCCESS: 'success';
    readonly ERROR: 'error';
}

const RequestState: RequestStateMap = {
    IDLE: 'idle',
    LOADING: 'loading',
    SUCCESS: 'success',
    ERROR: 'error'
} as const;

interface RequestData<T> {
    state: RequestStateMap[keyof RequestStateMap];
    data?: T;
    error?: string;
}

interface User {
    id: number;
    name: string;
}

const userRequest: RequestData<User> = {
    state: 'success',
    data: {id:1, name: "John"}
};

const failedRequest: RequestData<User> = {
    state: 'error',
    error: "Failed to fetch user"
}

 

 

2. type에는 없지만, interface에는 있는 선언 병합(declaration merging)

interface IState {
    name: string;
    address: string;
}

interface IState {
    population: number;
}

// 정상
const mergedInterface: IState = {
    name: "Kim",
    address: "Seoul",
    population: 500_000,
}

// Duplicate identifier 'TState'.
// type TState = {
//     name: string;
//     address: string;
// }

// type TState = {
//     population: number;
// }

 

 

 

 

 


참고 자료

  • 이펙티브 타입스크립트
  • 타입스크립트 GitBook
'Backend/TypeScript' 카테고리의 다른 글
  • JavaScript에서 Class가 결국 함수라는 게 어떤 의미일까?
  • 추상클래스와 제네릭 (실습)
  • Interface (인터페이스)
  • Iteration Protocol (+Symbol)
kimdozzi
kimdozzi
끝까지 포기하지 않으면, 내가 다 이겨!
  • kimdozzi
    도브로
    kimdozzi
  • 전체
    오늘
    어제
    • 분류 전체보기 (132)
      • Problem Solving (49)
        • Baekjoon (29)
        • Programmers (0)
        • LeetCode (17)
        • 삼성 유형 (2)
      • Computer Science (27)
        • Operating System (2)
        • Algorithms (13)
        • Network (6)
        • DataBase (6)
      • Backend (33)
        • JavaScript (0)
        • TypeScript (6)
        • Java (7)
        • Spring Boot (7)
        • Spring Security (6)
        • JPA (2)
        • Mybatis (1)
        • Junit5 (1)
        • Redis (3)
      • DevOps (14)
        • Git, Github (5)
        • docker (4)
        • AWS (3)
        • nginx (2)
      • etc (6)
        • IntelliJ (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 티스토리
    • 설정
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백준
    구간합
    Bucket
    점 업데이트
    알고리즘
    도커
    imos법
    interface
    S3
    누적합
    파이썬
    PrefixSum
    인덱스 시그니처
    온라인 쿼리
    오블완
    티스토리챌린지
    TypeScript
    컨테이너
    구간 업데이트
    오프라인 쿼리
    docker
    인덱서블 타입
    타입스크립트
    AWS
    segment tree
    CORS
    docker image
    삼성기출
    인터페이스
    세그먼트 트리
    python
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
kimdozzi
아이템13. type과 interface 차이점 알기
상단으로

티스토리툴바