TypeScript 命名空间与混入

命名空间 (Namespaces)

命名空间用于组织相关代码,避免全局作用域污染。通过 namespace 关键字定义,内部成员默认私有,需使用 export 暴露公共接口。

示例:

namespace Geometry {
  export interface Point {
    x: number;
    y: number;
  }

  export class Circle {
    constructor(public center: Point, public radius: number) {}
    area(): number {
      return Math.PI * this.radius ** 2;
    }
  }
}

// 使用命名空间
const point: Geometry.Point = { x: 0, y: 0 };
const circle = new Geometry.Circle(point, 5);
console.log(circle.area()); // 输出: $78.5398...$
嵌套命名空间
namespace OuterNamespace {
  export namespace InnerNamespace {
    export class MyClass {
      constructor(public value: number) {
        console.log(`InnerNamespace.MyClass instance created with value: ${value}`);
      }
      displayValue() {
        console.log(`Value: ${this.value}`);
      }
    }
  }
}

const myInstance6 = new OuterNamespace.InnerNamespace.MyClass(30);
myInstance6.displayValue(); // 输出: Value: 30

特点:

  1. 模块化组织:将相关类、接口、函数聚合
  2. 避免命名冲突:通过命名空间路径访问(如 Geometry.Circle
  3. 支持嵌套:可在命名空间内定义子命名空间

混入 (Mixins)

混入是一种组合多个类行为的模式,通过将工具类的方法动态合并到目标类中,实现多重继承效果。

实现步骤:

  1. 定义工具类(包含需混入的方法)
  2. 通过类型交叉和接口合并声明目标类结构
  3. 使用工厂函数实现方法注入

示例:

interface MyClass11 extends LogMixin, TimestampMixin { }

// 混入类 1:添加日志功能
class LogMixin {
  log(message: string): void {
    console.log(`[LOG]: ${message}`);
  }
}

// 混入类 2:添加时间戳功能
class TimestampMixin {
  getTimestamp(): string {
    return new Date().toISOString();
  }
}

// 混入函数
function applyMixins(targetClass: any, baseClasses: any[]): void {
  baseClasses.forEach((baseClass) => {
    console.log("Object.getOwnPropertyNames(baseClass.prototype)", Object.getOwnPropertyNames(baseClass.prototype))
    Object.getOwnPropertyNames(baseClass.prototype).forEach((name) => {
      if (name !== "constructor") {
        targetClass.prototype[name] = baseClass.prototype[name];
      }
    });
  });
}

// 目标类
class MyClass11 { }

// 应用混入
applyMixins(MyClass11, [LogMixin, TimestampMixin]);

// 使用混入后的类
const instance = new MyClass11();
instance.log("This is a log message"); // 输出 "[LOG]: This is a log message"
console.log(instance.getTimestamp()); // 输出当前时间戳

简单混入实现

class Person1 {
  constructor(public name: string) { }

  greet() {
    console.log(`Hello, my name is ${this.name}.`);
  }
}

// 2. 创建可以飞行能力的混入
function CanFly1<TBase extends new (...args: any[]) => any>(Base: TBase) {
  return class extends Base {
    fly() {
      console.log(`${this.name} is flying!`);
    }
  };
}

// 5. 使用混入创建复合类
// 首先创建一个具有飞行能力的Person
const FlyingPerson1 = CanFly1(Person1);

const flyingPerson1 = new FlyingPerson1("Bob");
flyingPerson1.greet();  // 输出: Hello, my name is Bob.
flyingPerson1.fly();    // 输出: Bob is flying!

特点:

  1. 行为组合:突破单继承限制
  2. 运行时动态性:方法在运行时注入
  3. 类型安全:通过接口声明确保类型正确
  4. 灵活解耦:工具类可独立维护

对比总结
特性命名空间混入
主要目的代码组织与隔离行为复用与组合
适用场景全局工具库、大型项目模块划分增强类功能、多继承模拟
实现方式静态声明 (namespace)动态注入 (工厂函数)
类型支持完整类型推断需显式接口声明合并
典型应用第三方库声明文件 (.d.ts)UI组件功能扩展

现代替代方案

  • 命名空间 → ES6 模块 (import/export)
  • 混入 → 组合式 API (Vue 3) 或装饰器
    但理解核心概念对处理遗留代码至关重要。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐