一个独特的双重继承模式,允许开发者以两种不同的方式扩展基类:直接继承
和工厂函数
方式。
实现方式
ts
// 定义Module接口
interface IModule {
exampleMethod(): number;
}
// 定义Module构造函数类型
interface ModuleConstructor {
new (): IModule;
(): typeof Module;
prototype: IModule;
}
// 实现Module类
const Module = (function() {
function Module(this: IModule) {
if (!new.target) {
return Module;
}
}
// 添加原型方法
Module.prototype.exampleMethod = function(this: IModule) {
// @ts-ignore
console.log('Method from Module',this.id);
};
return Module as unknown as ModuleConstructor;
})();
1. 类型系统设计
typescript
interface IModule {
exampleMethod(): number;
}
interface ModuleConstructor {
new (): IModule;
(): typeof Module;
prototype: IModule;
}
IModule
接口定义了模块的基本结构ModuleConstructor
接口实现了双重构造函数类型,支持两种实例化方式
2. 双重继承机制
Module类通过闭包和原型链操作实现了双重继承:
typescript
const Module = (function() {
function Module(this: IModule) {
if (!new.target) {
return Module;
}
}
return Module as unknown as ModuleConstructor;
})();
- 当使用
new
关键字时,创建普通实例 - 当作为函数调用时,返回构造函数本身
重点: new.target
元属性允许你检测函数或构造函数是否是通过 new
运算符被调用的。在通过 new
运算符执行的函数或构造函数中,new.target
返回一个指向 new
调用的构造函数或函数的引用。在普通的函数调用中,new.target
的值是 undefined
。
使用方式
通过以上方式创建的Module
即可以直接继承,也可以工厂方式继承。
1. 直接继承
typescript
class MyModule extends Module {
id = "my"
test() {
this.exampleMethod()
}
}
2. 工厂函数方式
typescript
class AnotherModule extends Module() {
id = "another"
test() {
this.exampleMethod()
}
}