我想覆盖一个方法并将不同的参数类型传递给它:
class Base {
public myMethod(myString: string): undefined {
return;
}
}
class Child extends Base {
public myMethod(myNumber: number): undefined {
return super.myMethod(String(myNumber));
}
}
然而,这会产生打字稿错误:
财产' myMethod'在类型'儿童'不能分配给它 基本类型的基础'基地'。输入'(myNumber:number)=>未定义' 不能分配给类型'(myString:string)=>未定义&#39 ;. 参数类型' myNumber'和' myString'是不相容的。 输入' string'不能分配类型'数字'。
有没有办法在不创建打字稿错误的情况下执行此操作?
答案 0 :(得分:4)
没有办法做到这一点*。在TypeScript中,inheritance implies subtyping,因此您不能从基类继承而不是它的有效子类型。
<子>
*
技术上并非如此,但我不会提及它们,因为它们是您不应该做的严重黑客攻击。
答案 1 :(得分:2)
正如其他人所说,这不是一个好主意,因为你打破Liskov替代。
您可以轻松完成的工作是提供同时包含string
和number
的覆盖。这允许您的类仍然可以在预期的基类的任何地方使用。
class Base {
public myMethod(myString: string): undefined {
return;
}
}
class Child extends Base {
public myMethod(myNumberOrString: number | string): undefined {
if (typeof myNumberOrString === 'number') {
return super.myMethod(String(myNumberOrString));
} else {
return super.myMethod(myNumberOrString);
}
}
}
答案 2 :(得分:1)
至少对于使用中间类的TypeScript v 4.02,似乎有一种方法,甚至对于返回类型也是如此。
但这打破了Liskov替换原则,因为它更改了返回类型,并且无法处理参数为字符串的情况。
因此,仅出于知识的考虑而值得一提,但是在代码审查中,我不会接受这种攻击,因为子类应该能够在不破坏功能的情况下替换基类。
class Base {
public myMethod(myString: string): string {
return myString + myString;
}
}
// weaken
// inspired by comment here: https://github.com/microsoft/TypeScript/issues/3402#issuecomment-385975990
class Interim extends Base {
public myMethod(x: any): any { return super.myMethod(x); }
}
class Child extends Interim {
public myMethod(myNumber: number): number {
return myNumber * myNumber;
}
}
// we can have a helper/utility for this
function weaken(klass: { new(...args: any[]): any; }, key: string) {
return class extends klass {
[key](...args: any[]) { super[key](...args); }
}
}
class ChildOther extends weaken(Base, 'myMethod') {
public myMethod(myNumber: number): number {
return myNumber * myNumber;
}
}
console.log((new Child()) instanceof Base); // true
console.log((new ChildOther()) instanceof Base); // true
console.log(new Base().myMethod('str')); // strstr
console.log(new Child().myMethod(3)); // 9
console.log(new ChildOther().myMethod(3)); // 9