在 TypeScript 中混合到已经实例化的对象
Mixin in TypeScript to already instantiated Object
我正在使用一个外部库,returns 回调中 A
类型的实例化对象 a
,其中 A
被定义为 接口(A
的class实现不被外部模块导出):
extLib.on("someEvent", ((a: A) => { /*...*/ });
现在我想将 B
类型的混合对象添加到 A
的现有实例中:
class B {
someExtension() { /* ... */ }
}
我目前的做法有点糟糕:
function Add_B(a: A): (A & B) {
// cast to intersection type
let _a = a as (A & B);
_a.someExtension = () => { /* ... */ }
return _a;
}
extLib.on("someEvent", ((a: A) => {
let _a = Add_B(a);
// mixin achieved, _a is of type (A & B)
});
现在有人知道更好的方法吗:
- 允许
B
具有可调用构造函数并使 B
可更新
- 结果为 less/cleaner 代码
- 比
A & B
交集类型 有更多表现力的类型
- 是否允许
B
上的 readonly
属性?
- 不会过多地干扰原型链(想想
static
成员)
?
这个怎么样:
interface A {
prop: string;
}
class B {
// so the same function can be shared between instance of B and instances of A & B
static someExtensionStatic = () => { /* ... */ }
someExtension = B.someExtensionStatic;
readonly prop2: number;
constructor(a?:A) {
if (a) {
let a1 = a as AandB;
a1.someExtension = B.someExtensionStatic;
return a1;
}
}
}
type AandB = A & B;
并在您的调用代码中:
extLib.on("someEvent", ((a: A) => {
let _a = new B(a) as AandB;
// mixin achieved, _a is of type (A & B)
}));
一个问题:B
的新实例的原型将在 B.prototype
,但 A
的实例将没有 B.prototype
的原型。
更新
原型差异的结果将导致以下结果:
var b1 = new B();
var isInstanceOf = b1 instanceof B; // true
var b2 = new B(a);
isInstanceOf = b2 instanceof B; // false
因此您应该决定结果对象的类型:
A 的实例,增加了 B 的成员
那么new B(a)
就没有意义了;静态 B.augment<T>: T & B
方法会更合适
- B 的实例,增加了 A 的成员;并且
instanceof
将有效工作
我正在使用一个外部库,returns 回调中 A
类型的实例化对象 a
,其中 A
被定义为 接口(A
的class实现不被外部模块导出):
extLib.on("someEvent", ((a: A) => { /*...*/ });
现在我想将 B
类型的混合对象添加到 A
的现有实例中:
class B {
someExtension() { /* ... */ }
}
我目前的做法有点糟糕:
function Add_B(a: A): (A & B) {
// cast to intersection type
let _a = a as (A & B);
_a.someExtension = () => { /* ... */ }
return _a;
}
extLib.on("someEvent", ((a: A) => {
let _a = Add_B(a);
// mixin achieved, _a is of type (A & B)
});
现在有人知道更好的方法吗:
- 允许
B
具有可调用构造函数并使B
可更新 - 结果为 less/cleaner 代码
- 比
A & B
交集类型 有更多表现力的类型
- 是否允许
B
上的readonly
属性? - 不会过多地干扰原型链(想想
static
成员) ?
这个怎么样:
interface A {
prop: string;
}
class B {
// so the same function can be shared between instance of B and instances of A & B
static someExtensionStatic = () => { /* ... */ }
someExtension = B.someExtensionStatic;
readonly prop2: number;
constructor(a?:A) {
if (a) {
let a1 = a as AandB;
a1.someExtension = B.someExtensionStatic;
return a1;
}
}
}
type AandB = A & B;
并在您的调用代码中:
extLib.on("someEvent", ((a: A) => {
let _a = new B(a) as AandB;
// mixin achieved, _a is of type (A & B)
}));
一个问题:B
的新实例的原型将在 B.prototype
,但 A
的实例将没有 B.prototype
的原型。
更新
原型差异的结果将导致以下结果:
var b1 = new B();
var isInstanceOf = b1 instanceof B; // true
var b2 = new B(a);
isInstanceOf = b2 instanceof B; // false
因此您应该决定结果对象的类型:
A 的实例,增加了 B 的成员
那么
new B(a)
就没有意义了;静态B.augment<T>: T & B
方法会更合适- B 的实例,增加了 A 的成员;并且
instanceof
将有效工作