Typescript Typescrip mixin:混合方法的返回类型
我遵循了那边的Typescript混合示例:,并做了一些更改Typescript Typescrip mixin:混合方法的返回类型,typescript,mixins,Typescript,Mixins,我遵循了那边的Typescript混合示例:,并做了一些更改 以下代码显示了这种关系:Point问题在于mixin创建结果类型的方式。如果我们查看export metod的最终类型,我们会发现它有3个重载: export(): { _mad: string; x: number; y: number;} export(): { _tag: string; x: number; y: number;} export(): { x: number; y: number;} 所以问题在于,不是重写该
以下代码显示了这种关系:Point问题在于mixin创建结果类型的方式。如果我们查看export metod的最终类型,我们会发现它有3个重载:
export(): { _mad: string; x: number; y: number;}
export(): { _tag: string; x: number; y: number;}
export(): { x: number; y: number;}
所以问题在于,不是重写该方法,而是最终为其创建多个重载。我怀疑mixin的实例类型最终是TNewMethods&InstanceType
如果我们对类型进行一些操作以替换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);
类点{
构造函数(公共x:number,公共y:number){}
出口(){
返回{x:this.x,y:this.y};
}
}
类型构造函数=new(…参数:any[])=>T;
类型OverrideeExportReturn={
new(…args:(T扩展new(…a:推断a)=>any?a:[]):
{export():ReturnType&TNewReturn}&
挑
}&选择
已标记的函数(基:T){
类标记扩展了基{
_标签:字符串;
构造函数(…参数:任意[]){
超级(…args);
这个。_tag=“”;
}
出口(){
返回{
…super.export(),
_标签:这个,
};
}
};
标记为未知的返回为OverrideeExportReturn;
}
函数Maded(基:T){
类Maded扩展基{
_疯狂:弦;
构造函数(…参数:任意[]){
超级(…args);
这个;
}
出口(){
返回{
…super.export(),
_疯了:这个,
};
}
};
返回与OverrideeExportReturn一样未知;
}
常量标记点=标记的(点);
设点=新标记点(10,20);
要点。_tag=“hello”;
console.log(point.export().\u标记);
常量MadedTaggedPoint=Maded(标记点);
const mad=新的MadedTaggedPoint(10,20);
console.log(mad.export()。\u mad);
console.log(mad.export().\u标记);
您有几个打字错误<代码>console.log(point.export()。_-mad)代码>应该是console.log(mad.export()。\u mad)
并在Madded
中导出\u标记
而不是\u mad
。但这里也有一个真正的问题。如果您做了我建议的更改,最后的mad.export()
将返回一个带有\u mad
但不带\u tag
的对象。这是您的真正问题吗?当然,我更正了拼写错误,因为MadedTaggedPoint混合了TaggedPoint,所以我认为mad.export()shuold具有标记属性
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);