这是我的演示代码:
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/