사내 Typescript 도입 전 Type alias vs Interface 분석하기

Typescript

이 글은 2024-04-28에 작성되었어요.

프롤로그


이번 포스팅은 아직 타입스크립트를 도입하지 않은 저희 회사를 기준으로 작성해보려고 합니다.

새로 입사하신 분께서 근 시일 내로 사내 코드의 일부분 부터 타입스크립트를 적용하게 되었는데요. 적용하기 앞서 사내에서 어떤 컨벤션을 가지고 타입스크립트를 적용하면 좋을지 도움이 되고 싶었습니다.

그 고민 중 한 가지가 Type alias, Interface 입니다.

각 기능을 적재적소에 사용하기 위해서 타입스크립트를 처음 실무에 도입하게 될 주니어의 시각으로 정리해보겠습니다.

성능


아무래도 차이점이 존재하는 n개의 기능을 비교할 때, 빠질 수 없는 것이 성능인 것 같습니다.

제가 2022년도 처음 타입스크립트에 대해 짧게나마 공부할 때, 기억나기엔 Interface가 성능에 더 유리하다는 말을 본 것 같은데요.

다시금 찾아본 자료에서는 둘의 성능 차이가 없다는 자료가 많더라고요. 실제로 어느 유튜버가 Type alias, Interface를 각각 사용해보고 성능 비교를 했는데 차이가 없다고 합니다.

좋습니다. 현재까지는 성능 차이가 존재하지 않으므로 두 기능이 필요한 경우에 맞춰 사용하면 좋을 것 같습니다.

사용 방식의 차이점


타입 확장

Type alias는 타입을 확장하기 위해서는 같은 이름으로 선언할 수 없습니다.

// 첫 선언 type A = { alpha: string } // 같은 이름으로 확장 할 수 없음 [Error] type A = { beta: string }

반대로 Interface의 경우 같은 변수명으로 선언하여도 작성한 타입들이 전부 병합됩니다. 그렇다고 해서 Type alias가 확장이 불가능하다는 것은 아니고, 변수명을 변경해서 ‘&’ 연산자를 이용하면 확장이 가능합니다.

단지 Interface는 같은 변수명으로도 선언 병합이 가능하다는 차이로 보입니다.

같은 이름으로 선언병합이 가능하다는 것이 장단점이 있을 것 같습니다. 단점을 굳이 꼽자면 혹여나 다른 위치에 선언된 변수를 못보고 지나칠 수 있다는 점(?)이 있겠습니다.

동일 속성에 대한 확장 처리 방식

Interface는 동일한 속성에 대해 확장을 허용하지 않습니다.

interface Alpha { beta: string echo: () => string } interface Charlie extends Alpha { beta: number// 에러 발생 echo: () => number// 에러 발생 }

반대로 Type alias는 속성을 자동으로 병합합니다. 이 경우에 한해서는 위 타입 확장을 좀 더 Type alias가 자유롭게 허용하는 느낌입니다.

역시나 다른 위치에 선언된 변수에 선언된 기존 속성을 못보고 지나친다면 단점이 될 수 있다는 점이 있습니다.

이렇게 보면 둘을 기능에 맞게 동시에 사용한다고 했을 때, 다소 헷갈릴 것 같다는 생각이 개인적으로 듭니다. 그래서 제가 만약 초기에 도입한다면 둘 중 하나를 선택해서 일관성을 맞추고 싶어지는 시점입니다.

기능의 다양성

Interface는 Tuple type을 지원하지 않아서 다른 방식으로 우회해야 합니다. 다만 이마저도 완벽한 Tuple은 아닙니다.

interface Alpha extends Array<string | number> { 0: string 1: number } const beta: Alpha = ['a', 1]// 이 방식은 가능하지만 const charlie: Alpha = [1, 'a']// 순서가 바뀐 이 방식은 사용할 수 없다.

제가 모르는 차이가 있을 수 있지만, 찾아본 바에 따르면 Type alias의 경우에는 웬만한 기능은 다 확장 또는 사용가능 한 것 같습니다.

그래서 단 둘을 놓고 봤을 때, ‘Interface의 기능 다양성 < Type alias의 기능 다양성’ 이렇게 느껴지긴 하네요.

타입 미리보기 제공


이건 IDE마다 다르겠지만, 최소한 제가 사용하는 VScode에서는 Type alias는 마우스를 호버할 시 선언된 속성을 미리보기에 띄워줍니다.

아쉽게도 Interface는 미리보기를 띄워주진 않습니다.

아마도 누군가는 ‘그냥 클릭해서 선언된 탭 띄워서 보면 되는데 뭐가 불만이지?’ 싶겠지만, 저는 원래도 하위 컴포넌트를 사용할 때 마우스를 호버해서 Props를 확인하거나 Cmd + i 를 눌러서 Props를 빠르게 확인하는 용도로 많이 사용했어서 훨씬 유용하다고 느껴졌습니다.

결론


원래 이 두 차이를 조사할 때만 하더라도 두 기능이 필요한 영역을 나누어 적재적소에 ‘둘 다’ 사용해야겠다는 생각이 지배적이었습니다.

여러 포스팅을 참고하면서 알아보니 개인적으로 Type alias가 Interface 보다 다양성을 제공하는 것 같아서 시각이 바뀌었습니다.

물론 Interface의 용도가 기존 라이브러리 확장 시나리오에서 유용하다는 점을 언급한 포스팅이 있었는데, 생각해보면 일리가 있는 것 같습니다. 아마도 새로운 버전을 업데이트 했을 시, 기존에 제공하던 타입의 이름이 변경되면 문제가 될 수 있겠더라고요.

하지만 저희 회사는 ‘라이브러리’를 제공하는 입장도 아니기 때문에 해당 부분은 고려 대상은 아닙니다.

정리하자면 저는 ‘Type alias’로 일관성있게 유지하면 모든 기능을 이용할 수 있다고 생각하고 좀 더 편하다는 느낌을 받았습니다.

아직 실무에 사용해보지 않았기 때문에 다소 편협한 시각으로 바라본 포스팅이 될 수도 있으니 넓은 마음으로 이해 해주시면 감사하겠습니다.