【问题标题】:Automatically override return type of several functions in a child class in TypeScript在 TypeScript 的子类中自动覆盖多个函数的返回类型
【发布时间】:2021-05-29 00:06:13
【问题描述】:

我有一个类,它有几个返回自身新实例的函数,我想扩展该类并让这些函数返回子类的实例。例如

class A {
    constructor(public val) {

    }

    getAnother(val): A {
        return new A(val);
    }

    next(): A {
        return this.getAnother(this.val + 1);
    }

    double(): A {
        return this.getAnother(this.val * 2);
    }
}

class B extends A {
    getAnother(val): B {
        return new B(val);
    }

    next(): B {
        return <B>super.next();
    };

    double(): B {
        return <B>super.double();
    };

    getValAsStr() {
        return String(this.val);
    }
}

let b = new B(1);

console.log(b.next().getValAsStr()); // logs "2"

这完成了我想要完成的工作,但理想情况下,我不需要在 B 类中重新实现 next()double() 并手动转换返回类型。我尝试了一种使用泛型的方法,它只允许我在 B 类中覆盖 getAnother(),但它破坏了 A 和 B 之间的多态关系

abstract class I<TResult> {
    constructor(public val) {

    }

    abstract getAnother(val): TResult;

    next(): TResult {
        return this.getAnother(this.val + 1);
    }

    double(): TResult {
        return this.getAnother(this.val * 2);
    }
}

class A extends I<A> {
    getAnother(val): A {
        return new A(val);
    }
}

class B extends I<B> {
    getAnother(val): B {
        return new B(val);
    }

    getValAsStr() {
        return String(this.val);
    }
}

有没有一种方法比我的第一种方法更干净,并且在 TypeScript 中保持 A 和 B 之间的关系?

【问题讨论】:

    标签: typescript inheritance covariance typescript-generics


    【解决方案1】:

    您可以使用多态this

    class A {
        constructor(public val) {
    
        }
    
        getAnother(val): this {
            return new A(val);
        }
    
        next(): this {
            return this.getAnother(this.val + 1);
        }
    
        double(): this {
            return this.getAnother(this.val * 2);
        }
    }
    
    class B extends A {
        getAnother(val): this {
            return new B(val);
        }
    
        getValAsStr(): string {
            return String(this.val);
        }
    }
    

    (未经测试)

    【讨论】:

    • 嗯,是的。在我的真实世界用例中,我正在尝试构建一个处理器链。链中的每个节点都有一个函数,该函数接受来自其父节点的输出并可以返回一些新类型。所以本质上 A 实际上是 A 并且next&lt;TNext&gt;() 返回 A。所以我不认为我可以使用多态 this 因为我需要在返回类型中指定不同的泛型。但这回答了我提出的问题,因此我可以将其作为一个单独的问题发布。
    猜你喜欢
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-01
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多