声明合并是 TS 中的一个独特的概念,是指编译器会把程序中多个地方具有相同名称的声明合并为一个声明。好处是可以把程序中散落在各处的同名合并在一起,可以避免对成员的遗漏。

:::info 并不建议在项目中使用声明合并的方式。这个特性,主要是 TS 为了照顾以前的老旧项目产生的。 :::

接口合并

对于同名接口,TS 会进行合并:

  1. interface A {
  2. x: number;
  3. }
  4. interface A {
  5. y: number;
  6. }
  7. let a: A = {
  8. x: 1,
  9. y: 1,
  10. };

在接口中:

  • 声明了同名的属性,但是类型不一致,会报错
  • 声明了同名的函数,参数类型和返回值类型不一致,则被认为是函数重载

命名空间合并

对于同名的命名空间, TS 会进行合并:

namespace Shape {
  let a = 1; // 只在命名空间内可用

  export let b = 2; // 导出到全局

  export function circle(r: number) {
    return Math.PI * r * r;
  }
}

namespace Shape {
  export function square(x: number) {
    return x * x;
  }
}

Shape.b;
Shape.circle(1);
Shape.square(1);

需要注意的是:

  • 导出的成员是不可以重复定义的,函数也不可以

命名空间与函数或类的合并

命名空间与函数的合并:

function Lib() {}
namespace Lib {
  export let version = '1.0';
}
console.log(Lib.version);

相当于函数对象上添加了一些属性。

命名空间与类的合并:

class C { }
namespace C {
  export let state = 1
}
console.log(C.state);

相当于在类上添加了一些静态属性。

:::info 注意:命名空间的声明一定要放到函数或类的后面。 :::

命名空间与枚举类型的合并

enum Color {
  Red,
  Yellow,
  Bule
}
namespace Color {
  export function mix() {

  }
}

console.log(Color.mix())

相当于给枚举类型对象添加了一个属性