Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript Typescrip mixin:混合方法的返回类型_Typescript_Mixins - Fatal编程技术网

Typescript Typescrip mixin:混合方法的返回类型

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;} 所以问题在于,不是重写该

我遵循了那边的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;}
所以问题在于,不是重写该方法,而是最终为其创建多个重载。我怀疑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);