TypeScript 接口合并, 你不知道的妙用

2023-10-20 15:55:33 浏览数 (2)

初识

声明合并(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 声明:

代码语言:javascript复制
// 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'

// 


	

0 人点赞