프로그래밍풀스택 개발자

TypeScript에서 선언 병합(Declaration Merging)이란 무엇이며 실제로 어떻게 작동합니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

질문의 배경

선언 병합(Declaration Merging)은 TypeScript의 고유한 기능으로, 동일한 이름을 가진 여러 선언을 하나의 엔터티로 결합할 수 있게 해줍니다. 이는 JavaScript에 대한 타입 시스템으로서의 TypeScript의 역사와 관련이 있습니다. 많은 서드파티 라이브러리가 인터페이스, 함수, 네임스페이스를 선언했으며, TypeScript는 라이브러리의 원본 코드를 수정하지 않고도 이를 확장할 수 있게 해주어야 했습니다.

문제

복잡한 API와 서드파티 JS 라이브러리에 타입을 지정할 때, 책임을 분리해야 할 수 있습니다. 예를 들어, 모듈의 타입을 확장하거나, 인터페이스 필드를 추가하거나, 이름을 결합할 수 있습니다. 그러나 대부분의 언어는 이러한 선언 병합을 지원하지 않습니다.

해결책

TypeScript는 동일한 이름을 가진 인터페이스, 네임스페이스, 함수, 클래스의 선언을 병합할 수 있도록 해주어 API가 확장 가능하도록 만듭니다. 이는 서드파티 타입을 확장하거나 라이브러리에 사용자 정의 메서드를 추가하며 모듈화된 코드를 조직하는 데 사용됩니다.

코드 예시:

// 인터페이스 병합 interface User { id: number; } interface User { name: string; } const u: User = { id: 1, name: "Jack" }; // 네임스페이스 + 함수 병합 function greet() { return "안녕하세요!"; } namespace greet { export function loud() { return "안녕하세요!!"; } } greet(); // "안녕하세요!" greet.loud(); // "안녕하세요!!"

주요 특징:

  • 인터페이스, 네임스페이스가 있는 함수, 네임스페이스가 있는 enum을 결합할 수 있지만, 타입은 결합할 수 없습니다.
  • 확장 가능한 API 및 전역 선언 확장을 설명하는 데 사용됩니다.
  • 외부 라이브러리의 타입을 안전하게 수정/확장할 수 있게 해줍니다.

속임수가 있는 질문들.

타입 별칭(type alias)을 인터페이스처럼 병합할 수 있습니까?

아니요, 타입 별칭(type alias)은 병합할 수 없습니다. 동일한 이름을 가진 여러 타입을 선언하려고 하면 컴파일 오류가 발생합니다.

type T = { a: string }; type T = { b: number }; // 오류

TypeScript가 인터페이스/네임스페이스의 필드를 무작위로 삽입합니까?

병합된 구조는 항상 선언 순서대로 만들어지며, 동일한 속성 이름이 있을 경우 마지막 선언이 "승리"합니다.

인터페이스의 메서드가 하나의 함수로 병합됩니까?

아니요, 서로 다른 인터페이스에서 동일한 이름의 메서드는 하나의 함수로 병합되지 않습니다. 시그니처가 일치하더라도 TypeScript는 "둘 다"를 구현하는 것을 허용하지 않습니다.

자주 발생하는 오류 및 안티 패턴

  • 네임스페이스가 없는 타입 별칭이나 enum을 병합하려고 하면 오류가 발생합니다.
  • 인터페이스 내에서 서로 다른 타입의 반복 필드는 충돌하여 병합되지 않습니다;
  • 의도하지 않은 병합 사용 — 이는 코드 가독성을 저하시킵니다.

실제 예시

부정적인 사례

회사가 서로 다른 필드와 동일한 이름의 서로 다른 타입을 가진 전역 인터페이스 Window를 두 번 정의합니다. 빌드 중에 빌드 도구는 문제를 감지하지 못하며, 실행 시 예기치 않은 타입 충돌이 발생합니다.

장점:

  • 원본을 수정하지 않고 인터페이스를 "확장"할 수 있는 빠른 방법.

단점:

  • 충돌하는 이름은 버그를 초래하며 찾기 어렵습니다.
  • 종종 타입의 전체 구조를 이해하는 데 어려움을 줍니다.

긍정적인 사례

서드파티 라이브러리에 대한 d.ts 파일을 작성하고, 라이브러리를 수정하지 않고 API 인터페이스를 개별 모듈로 확장하며, 모든 확장은 문서화되어 있고, Naming 정책이 위키에 설명됩니다.

장점:

  • 서드파티 API를 안전하게 확장할 수 있습니다.
  • 점진적으로 개선 사항과 추가 기능을 도입할 수 있습니다.

단점:

  • 문서화된 일치사항 및 네이밍을 유지해야 합니다.
  • 엄격한 네이밍 정책 없이 큰 팀에서는 충돌 위험이 증가합니다.