Typescript 만의 특별한 예로 '선언 병합' 개념이 있습니다. 이 개념을 이해한다면 기존의 Javascript와 작업을 할 때 이점이 많아 집니다. 또한 이 개념은 고급 추상화 개념으로의 문을 열어줄 것입니다.
"선언 병합"은 컴파일러가 같은 이름으로 선언된 두 개의 개별적인 선언을 하나의 정의로 병합하는 것을 뜻합니다.
Typescript에서 선언은 네임스페이스, 타입, 값 중 한 종류 이상의 엔티티를 생성합니다. 각 선언은 아래 표의 X 로 표시된 병합 결과물을 만듭니다.
가장 일반적이고 간단한 선언 병합 유형은 인터페이스 병합입니다.
interface Box {
height: number;
width: number;
}
interface Box {
scale: number;
}
let box: Box = {height: 5, width: 6, scale: 10};
인터페이스의 비-함수 멤버는 고유하거나 같은 타입이어야 합니다. 그렇지 않다면 컴파일러는 오류를 일으킵니다.
함수 멤버의 경우, 이름이 같은 경우 동일한 함수에 대한 오버로드하는 것으로 처리합니다. 또한 나중에 선언된 인터페이스의 경우 더 높은 오버로드 우선 순위를 갖게 됩니다.
interface Cloner {
clone(animal: Animal): Animal;
}
interface Cloner {
clone(animal: Sheep): Sheep;
}
interface Cloner {
clone(animal: Dog): Dog;
clone(animal: Cat): Cat;
}
interface Cloner {
clone(animal: Dog): Dog;
clone(animal: Cat): Cat;
clone(animal: Sheep): Sheep;
clone(animal: Animal): Animal;
}
나중에 병합되어 오버로드 될 수록 첫 번째에 위치합니다.
그러나 이 규칙엔 예외가 존재합니다. 함수 시그니처에 단일 문자열 리터럴 타입인 매개변수가 있을 경우 시그니처는 병합된 오버로드 목록의 맨 위로 올라오게 됩니다.
interface Document {
createElement(tagName: any): Element;
}
interface Document {
createElement(tagName: "div"): HTMLDivElement;
createElement(tagName: "span"): HTMLSpanElement;
}
interface Document {
createElement(tagName: string): HTMLElement;
createElement(tagName: "canvas"): HTMLCanvasElement;
}
interface Document {
createElement(tagName: "canvas"): HTMLCanvasElement;
createElement(tagName: "div"): HTMLDivElement;
createElement(tagName: "span"): HTMLSpanElement;
createElement(tagName: string): HTMLElement;
createElement(tagName: any): Element;
}