我遵循了那里的Typescript Mixins示例:mixin,并进行了一些更改,
以下代码显示了这种关系:Point <= TaggedPoint <= MadedTaggedPoint,并且有一个'export'方法返回一个由基类和当前类的属性合成的对象,问题是当多次应用mixin时,那么生成的类的实例将无法正确识别混合的'export'方法的返回类型:
from sklearn.metrics import mean_squared_error, explained_variance_score
mae = mean_squared_error(true, predicted)
print('Mean Squared Error : {}'.format(mae))
rmse = np.sqrt(mean_squared_error(true, predicted))
print('Root Mean Squared Error : {}'.format(rmse))
evs = explained_variance_score(true, predicted)
print('Explained Variance Score: {}'.format(evs))
答案 0 :(得分:0)
问题是mixins创建结果类型的方式。如果我们查看导出方法的最终类型,我们会看到它有3个重载:
export(): { _mad: string; x: number; y: number;}
export(): { _tag: string; x: number; y: number;}
export(): { x: number; y: number;}
所以问题在于,您最终没有为方法覆盖,而是为其创建了多个重载。我怀疑mixin的实例类型最终是TNewMethods & InstanceType<T>
。
如果我们对实例类型进行一些手术以替换export
方法,则可以覆盖实例类型:
class Point {
constructor(public x: number, public y: number) { }
export() {
return { x: this.x, y: this.y };
}
}
type Constructor<T> = new (...args: any[]) => T;
type OverrideExportReturn<T extends Constructor<Point>, TNewReturn> = {
new (...args: (T extends new (...a: infer A) => any ? A: [])):
{ export(): ReturnType<InstanceType<T>['export']> & TNewReturn } &
Pick<InstanceType<T>, Exclude<keyof InstanceType<T>, 'export'>>
} & Pick<T, keyof T>
function Tagged<T extends Constructor<Point>>(Base: T){
class Tagged extends Base {
_tag: string;
constructor(...args: any[]) {
super(...args);
this._tag = "";
}
export() {
return {
...super.export(),
_tag: this._tag,
};
}
};
return Tagged as unknown as OverrideExportReturn<typeof Tagged, {_tag: string }>;
}
function Maded<T extends Constructor<Point>>(Base: T) {
class Maded extends Base {
_mad: string;
constructor(...args: any[]) {
super(...args);
this._mad = "";
}
export() {
return {
...super.export(),
_mad: this._mad,
};
}
};
return Maded as unknown as OverrideExportReturn<typeof Maded, {_mad: string }>;
}
const TaggedPoint = Tagged(Point);
let point = new TaggedPoint(10, 20);
point._tag = "hello";
console.log(point.export()._tag);
const MadedTaggedPoint = Maded(TaggedPoint);
const mad = new MadedTaggedPoint(10, 20);
console.log(mad.export()._mad);
console.log(mad.export()._tag);