728x90

들어가며

TS를 사용하다보면 언제 type alias와 interface를 구분해서 사용할지 모호한 경우가 많습니다. interface방식이 확장성이 좋다는 말이 많은데, 사실 유니언 타입을 사용하면  type alias 방식도 확장이 가능합니다.

// interface
interface Point {
  x: number;
  y: number;
}

interface SetPoint {
  (x: number, y: number): void;
}


// type alias

type Point = {
  x: number;
  y: number;
};

type SetPoint = (x: number, y: number) => void


이에 대해서 우아한 타입스크립트와 stack overflow의 내용을 정리하여 언제 type aliases(이하 타입별칭) 방식을 쓰고 언제  interface(인터페이스)를 사용할 지 구분하려고 합니다.

타입 별칭만 쓸 수 있는 경우

// primitive
type Name = string;

// object (인터페이스도 사용가능)
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };

// union
type PartialPoint = PartialPointX | PartialPointY;

// tuple
type Data = [number, string];

 

타입 별칭은 인터페이스와 달리 원시값, 유니온 , 튜플 타입에서 사용이 가능합니다.

 

모두 사용 가능한 경우

이외에는 문법적 차이가 존재하지만 두 가지 방법 모두 구현이 가능합니다.

 

객체 선언

type BirdType = {
  wings: 2;
};

interface BirdInterface {
  wings: 2;
}

const bird1: BirdType = { wings: 2 };
const bird2: BirdInterface = { wings: 2 };

// Because TypeScript is a structural type system,
// it's possible to intermix their use too.

const bird3: BirdInterface = bird1;

두 가지 방법모두 사용할 수 있으면  타입스크립트는 구조적 타입시스템을 가지기 때문에 혼용해서 사용가능합니다.

 

확장 ( 출처 )

Interface extends interface

interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }

Type alias extends type alias

type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };

Interface extends type alias

type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }

Type alias extends interface

interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };

 

implement

interface Point {
  x: number;
  y: number;
}

class SomePoint implements Point {
  x = 1;
  y = 2;
}

type Point2 = {
  x: number;
  y: number;
};

class SomePoint2 implements Point2 {
  x = 1;
  y = 2;
}

type PartialPoint = { x: number; } | { y: number; };

// FIXME: can not implement a union type
class SomePartialPoint implements PartialPoint {
  x = 1;
  y = 2;
}

 

interface의  타입별칭과의 차이점

인터페이스의 타입 별칭과의 차이점은 interface는 열려 있고 type 별칭은 닫혀 있다는 점입니다. 
이는 interface를 두 번째로 선언함으로써 확장할 수 있다는 뜻입니다. 이를 선언 병합(Declaration merging)이라고도 합니다.

interface Kitten {
  purrs: boolean;
}

interface Kitten {
  colour: string;
}

// In the other case a type cannot be changed outside of
// its declaration.

type Puppy = {
  color: string;
};

type Puppy = {
  toys: number;
};

 

이러한 점이 interface가 더욱 확장성이 높다고 하는 근거입니다.

 

그럼 어떤 것을 사용해야할까?

우아한 타입스크립트 with React 에서 배달의 민족팀이 사용하는 방법과 위의 정보를 요약하면 아래와 같습니다.

 

 

원시타입, 유니온, 튜플 : 이 3가지의 경우에는 타입 별칭밖에 사용할 수 없습니다.

유틸리티 타입타입 별칭 밖에 사용할 수 없습니다.  ex)type PartialUser = Partial<User>

컴퍼넌트의 props의 경우 :  확장성이 높은 interface 사용  ex) Dialog컴퍼넌트를 만들때 다른 컴퍼넌트와 공유되는 interface

객체 지향적으로 코드 작성 시 : 특히 상속의 관련된 경우 interface

계산되는 타입(Computed value)타입 별칭 사용 

const colors = {
  primary: '#00f',
  secondary: '#0f0',
  danger: '#f00',
} as const;

// computed value로부터 타입 만들기
type ColorKey = keyof typeof colors;

 

이외에는 팀적 컨벤션에 따라 달라졌습니다. 

type은 추론이 더 잘된다는 장점이 있어서 type 위주로 쓰는 팀도 있고 ,  정적이거나 작은 범위는 type 그 외에는 interface를 사용하는 팀도 있습니다.

 

저는 후자의 방식을 선호해서 대부분 interface로 사용하고 있습니다.

 

 

 

 

 

출처  및  참고문헌

https://stackoverflow.com/questions/37233735/interfaces-vs-types-in-typescript/52682220#52682220

https://www.typescriptlang.org/play/?ssl=51&ssc=38&pln=51&pc=45#code/PTAEBUAsFMCdtAQ3qALgdwPagLaIJYB2ammANgM4mgAm0AxmcgqjKBZIgA4KYBmSQgCgQoTACMAVg1QAuUEVRw+ietCqJCNNAE8eSMvkQV1AOhHALEGDqQoAbnFsV8OfE1gAaQdr6ZYaGw4mBSooPSYOMHE9MbqVqphrAgUiDjQ5kKoeggAQviwNOA5oAC8oADeQqCg6EQA5hTyAEwA3EIAvu1CisqqeQU0AJKESrAqapXVtQ1NoG2dQkIRhKGg4oMAjPL5hcX65RUzhI0toF3LmKthG4XNO4MjYxMIh8en8+fdorkMiACuJggOQAyvRYPguGF8Bp2KhYP96Kh-rBEGRdPoKDpQtAcJ4rPhUAByKhcEIucRkFjYXqwNwAD0C0AKoEB1MwmRWa1uNAAzA9Ck8+pNyjzNt8wFBoLZxJhWOx-lwybAwtB6UotA0xMkArSXhotBizFZ9gg0UYTFQaNhWDDQPYjApRnATEj8FcjRRvOhIO5oATneN+lROI4kKAANbSrCFTLZfQAeXQ6LehEwSJRhDR8nh-wQHVAADJQLsijl2vGEAAlCREMqVUBpjOwLNkeQqSj5oslx6Bl7dPX9UAABWgqnTEdAao1NCopdNUxqETImBRfH+bbQCOg7RqfEM6nbaJM7Q6PT7Q4Awr76FHiNPoFo573nkOqkvyKvxhuj53d6B93wQ8AOPHdFiEKkwkwZN5CTFMGzqE45mabwm2RFtsy3PMvgg6AwnoG873ka98FvR96yORCPhQ8JPzXH8QM7bxAOAjsgQuE1ODCVJ8Bob0EHgCIokfbQdFXVkgUHNQqEwRwAkrBJDDiChTFAEEeHofA+FItEyB0bxxD+NlQDE-4ZjIdF6jw9Y8LGKdYFgfwrHSChUislTQCGARTNASBZLgMQ5KZADyBXKj7Mc2AvRM8TYmEUQTAQPz0GBHgwQhKFwk0UAuEch06DQF0As0bRghQPx6DZGhnPUNz1FqGBiBjCMtTqeUpPqwwo1AEiyMITJoPggjSLvdphr6+tBolUAE0IBA8EkfxaC0vg4EfSZDIwaByMrAwLXq+wqA6igEhQVhEGhC9pLsXgeGIEqjT25SbvCFcTBocxRCgO10k0KgfLiqd1REwQnVfDbbDoRhkC1QkEnYBgrm0VBXAyJYOtAABpQkNUXHKUSi+RZXIMdCFPdGroQbHUFx99aJXFF5FCCETnJqwRmCuUYACWIgUQR64rTG4EAIzQrO0VdUBcAr+AJKXaAYDwLvdfqll24dFS4WxDmmZd-CZ+EGlPbp1c17W8dQTBsXkQh-hwQzYGNpZRAAEWgO6aC1D1TICepMGPbxbStFa1sISYIg3bRDKQKwyRcFGwyW-m5vqZXHFUgAJaDoCCvwAi4f5KVIvSgbj6BqtEStosJElw02uzYgs6g8G65IcFBjrMlEWbeAEZIbLWeAKC-a684R5kTgMdF+GC8urKsXn6uQVdDSr+0jsp6Kg7hVRJ388YwqsVh4EQbQ7X5v3MG0LgmEmS2d5VWRnbASAaa4JoQFCXf9-3aDTCE4AABHPMoQVYUGALyAA7M0XkUDeQAFZgBV3BJCVAABaY6aDDpoKrsAeBzQABsAAOZopCAAMABifBxDSHNDIUIIAA

 

TS Playground - An online editor for exploring TypeScript and JavaScript

The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.

www.typescriptlang.org

우아한 타입스크립트 with 리액트 (우아한형제들 웹프론트개발그룹 지음)

 

+ Recent posts