javascript - 如何解决具有不同数据类型的 Angular 4 的方法重载问题?

标签 javascript angular typescript

这是我的演示代码:

class First {
    x: string;
    y: string;
    constructor() 
    {
    }
    setValue(x: string, y: string): void {
        this.x = x;
        this.y = y;
        console.log("setValue In A value of x and y:", this.x, this.y);
    }
    getValue(): void {
        console.log("getValue In A value of x and y:", this.x, this.y);
    }
}

class Second extends First {
    x: string = '5';
    z: number;
    constructor() {
        super();
    }

    setValue(z: number, y: string) {
        this.z = z;
        this.y = y;
        return super.setValue(this.x, this.y); 
    }
}

我有两个类(class),第一类和第二类。 但是在第二节课中,我遇到了以下错误

Property 'setValue' in type 'Second' is not assignable to the same property in base type 'First'. Type '(z: number, y: string) => void' is not assignable to type '(x: string, y: string) => void'. Types of parameters 'z' and 'x' are incompatible. Type 'string' is not assignable to type 'number'

我尝试了一些可能的解决方案,方法是在 Class first 方法中将类型指定为“any” 还尝试使用另一个补丁,将 Class second 中的联合类型指定为 z: string |数

但这两种解决方案都是对问题的拼凑,但无法解决原始问题,因为我们可以传递字符串或数字,但实际上,它只接受字符串。 如果假设该方法只接受一个参数,则清除更多,则上述任何解决方案都将不起作用。

我希望我的问题已经清楚了。

最佳答案

问题是您尝试做的事情违反了 OOP 原则。假设允许您想要的重载,请考虑以下流动代码:

let f: First = new Second() // Assign a derived class to a base type reference
f.setValue("Not a number", "y") // Second is getting a string insead of a number

在上面的代码中,Second 将接收一个 string 作为第一个参数而不是数字,因为我们是通过基类引用调用的。

一种解决方案是保留原始签名并添加带有数字的签名,并确保两者都按预期工作:

class First {
    x: string;
    y: string;
    constructor() 
    {
    }
    setValue(x: string, y: string): void {
        this.x = x;
        this.y = y;
        console.log("setValue In A value of x and y:", this.x, this.y);
    }
    getValue(): void {
        console.log("getValue In A value of x and y:", this.x, this.y);
    }
}

class Second extends First {
    x: string = '5';
    z: number;
    constructor() {
        super();
    }

    setValue(x: string, y: string)
    setValue(z: number, y: string)
    setValue(xz: string | number, y: string) {
      if (typeof xz == 'number') {
        this.z = xz; // xz is number so we got called with z
        this.y = y;
        return super.setValue(this.x, this.y);
      } else {
        // xz is string so we got called with x
        return super.setValue(xz, y);
      } 
    }
}

let f: First = new Second() // Assign a derived class to a base type reference
f.setValue("Not a number", "y") // Works as expected now

通常,当您派生类时,您可以添加到该类的公共(public)签名,但不能从中获取,因为这会破坏 OOP 的承租人,即您可以安全地将派生类分配给基类引用。

注意 Typescript 的类型非常灵活,您可以进行一些类型手术以从 First 中删除 setValue 以获得Second 中的自由度更高。我可以提供这样的解决方案,但我强烈建议不要这样做。

关于javascript - 如何解决具有不同数据类型的 Angular 4 的方法重载问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53941519/

相关文章:

javascript - 如何传递仅在回调创建时存在的参数

javascript - AngularFire 取消 AngularJS 数组中的项目

angular - Webpack 和 TypeScript 上的 SignalR : cannot find module './NodeHttpClient'

Angular 2 - 过滤管回空

angular - 最简单的 Angular 轮播

javascript - 在 next.js 中调试获取操作

javascript - 无法获取独立范围的值

angular - rxjs/可观察到的 : Execute functions one by one and pass parameters of functions as result of previous function

Angular 2 - 呈现 innerHtml 后的事件

javascript - 是否有一种优雅的方法来检查 POST 请求正文是否与端点处的预期参数匹配?