아이템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)
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

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

  • 최근 글

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

티스토리툴바