익히 알듯이, typescirpt에서 type을 정의하는 방법은 type
, interface
이렇게 두 가지가 있다.
type
을 쓰든, interface
를 쓰든 예외 상황을 제외하고는 모든 타입 선언을 둘 중에 하나를 쓰기로 규칙을 정하여 통일 하여 사용하는게 협업하거나, 코드를 작성할 때의 고민을 덜어주는데에 효과적일 것 이다.
필자는 class
가 interface
를 implements
하는 경우를 제와한 일반적인 타입 체킹을 할 때는 type
를 사용하는데, 그 이유를 여러분과 공유하고자 한다.
TMI) 사실 class
에서 implements
를 할 때도 type
으로 정의 된 타입을 사용해도 된다. 그러나 interface
라는 단어가 java
등의 다른 언어에서 클래스를 추상화 할 때 많이 쓰이기 때문에 typescript
에서도 그 관습을 따라가고자 해서, 필자는interface
를 쓴다.
interface
는 type
에 비해 상대적으로 지원되는 타입의 형식이 적다.Primitive
, Union
, Tuple
등 많이 사용되어지지만 interface로는 정의가 불가능한 타입들이 있다. type을 정의할 때 interface
나 type
둘 중 하나를 일괄적으로 사용해야 한다면, 위의 타입들을 제공하는 type
을 이용해 type 선언을 하는게 좋다고 생각한다.
'''Union types'''
type Fruit = 'apple' | 'pear' | 'orange';
type Vegetable = 'broccoli' | 'carrot' | 'lettuce';
type HealthyFoods = Fruit | Vegetable;
'''Primitive & Union types'''
type Nullish = null | undefined;
type Num = number | bigint;
'''Function types'''
type row = [colOne: number, colTwo: string];
interface
는 Declaration merging
의 여지가 있다.이 부분에 관해서는 ts개발자들 사이에서 의견이 분분할 것 같다. 일단 필자의 의견을 먼저 말해보자면, interface
의 Declaration merging
는 잘 활용하기 어렵고, 오히려 코드를 짜는데 방해가 되거나 가독성을 낮출 수 있는 여지가 있다고 생각한다.
그럼 일단 Declaration merging이란 뭘까?
interface
를 정의 한 이후에, 똑같은 이름의 interface
를 정의하면 컴파일러가 먼저 정의된 interface
를 자동으로 병합하는 행위를 뜻한다.
글보다 코드를 보면 더 이해하기 쉬우리라 생각된다.
interface Box {
height: number;
width: number;
}
interface Box {
scale: number;
}
위 코드는
interface Box {
height: number;
width: number;
scale: number;
}
이 코드와 같다.
지금이야 전자의 코드에서는 Box interface
에 정의가 2번 밖에 없으니 가독성이괜찮지만, 코드가 거대해지면 Box interface
가 여러번 정의되어서 Declaration merging이 일어났는지 몇번일어났는지 파악하기가 어렵다. 그래서 interface
를 쓸 때 쓰더라도, Declaration merging을 의도적으로 사용하는 것은 좋지 않다고 생각한다.
그리고 이 기능의 가장 충격적인 결점은, typesciprt 컴파일러는 interface
가 더 expand
될 가능성이 있다고 판단을 되는지, 아래 코드는 컴파일 에러를 내뿜는다.
필자는 이 에러의 명확한 이유를 찾진 못했고, interface
는 Declaration merging이 일어날 여지가 있기 때문에 field가 더 늘어날 수 도 있어서 컴파일에러가 나온다고 파악했다.
이 에러는 놀랍게도 Animal
type을 type
으로 정의하면 해결된다.
typescript에서 type 정의는 interface
보다는 type
으로 하자!
class interface
를 추상화 하는 경우가 아니라면 딱히 interface
를 쓸 이유가 없는 것 같다.
필자는 무식이 가득한 주니어이기 때문에 여러분들의 피드백을 너무너무 환영합니다! 감사합니다😀👍
참고
https://www.typescriptlang.org/docs/handbook
https://stackoverflow.com/questions/37233735/typescript-interfaces-vs-types
오오... 타입과 인터페이스의 차이를 막연하게만 알고 있었는데, 명확하게 짚어 주시니 큰 도움이 되네요.