如何解决不同数据类型的Angular 4的方法重叠问题?

时间:2018-12-27 07:45:41

标签: 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); 
    }
}

我有两个班,第一和第二。 但是在第二课中,我遇到了错误

  

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 |数字

但是两种解决方案都是解决该问题的方法,但不能解决原始问题,因为我们可以传递字符串或数字,但实际上,它只接受字符串。 如果假设该方法仅接受一个参数,则清除更多内容,则上述解决方案均无效。

我希望我的问题很清楚。

1 个答案:

答案 0 :(得分:1)

问题在于您尝试做的事情违反了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

通常,在派生类时,可以添加到该类的公共签名,但是不能从中获取,因为那样会破坏OOP的租户,您可以安全地将派生类分配给基类引用。 / p>

注意:打字稿的类型非常灵活,您可以进行某种类型的手术,从setValue中删除First,以便在{ {1}}。我可以提供这样的解决方案,但强烈建议您反对。