初识
声明合并(Declaration Merging) 是 Typescript
的一个高级特性,顾名思义,声明合并
就是将相同名称的一个或多个声明合并为单个定义。
例如:
代码语言:javascript复制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;
}
// Cloner 将合并为
//interface Cloner {
// clone(animal: Dog): Dog;
// clone(animal: Cat): Cat;
// clone(animal: Sheep): Sheep;
// clone(animal: Animal): Animal;
//}
声明合并最初的设计目的是为了解决早期 JavaScript
模块化开发中的类型定义问题。
- 早期的 JavaScript 库基本都使用全局的命名空间,比如 jQuery 使用 , lodash 使用 _。这些库通常还允许对命名空间进行扩展,比如 jQuery 很多插件就是扩展 的原型方法
- 早期很多 Javascript 库也会去扩展或覆盖 JavaScript 内置对象的原型。比如古早的 RxJS 就会去 「Monkey Patching」 JavaScript 的 Array、Function 等内置原型对象。
尽管这些方案在当今已经属于「反模式」了,但是在 Typescript 2012 年发布那个年代, jQuery 还是王者。
Typescript 通过类型合并这种机制,支持将分散到不同的文件中的命名空间的类型定义合并起来,避免编译错误。
现在是 ES Module 当道, 命名空间的模式已经不再流行。但是不妨碍 声明合并 继续发光发热,本文就讲讲它几个有趣的使用场景。
JSX 内置组件声明
Typescript 下,内置的组件(Host Components
) 都挂载在 JSX
命名空间下的 IntrinsicElements
接口中。例如 Vue 的 JSX 声明:
// somehow we have to copy=pase the jsx-runtime types here to make TypeScript happy
import type {
VNode,
IntrinsicElementAttributes,
ReservedProps,
NativeElements
} from '@vue/runtime-dom'
//