Reputation: 6926
class A {
game(a: string): string{
return a;
}
}
class B extends A {
game(c: string, b: number): string{
return c + ' ' + b.toString();
}
}
let a = new A();
console.log(a.game('Name'));
let b = new B();
console.log(b.game('Surname', 1986));
I'm getting this type error to the compiler
Property 'game' in type 'B' is not assignable to the same property in base type 'A'. Type '(a: string, b: number) => string' is not assignable to type '(a: string) => string'
What is the best practice for something like that?
Upvotes: 1
Views: 2207
Reputation: 187134
One of the important aspects of inheritance is that you can treat any child class just like its parent class. And that means you must preserve the public interface of parent class instances in the child class instances. It should always be type safe to use a child class as if it were a parent class instance.
But in your case you break that contract by changing the interface. That's not allowed.
For example, you should be able to pass any subclass of A
to this function:
function getGame(instance: A) {
return instance.game('name')
}
However, if you were to pass an instance of B
to this function it would break since game
requires two arguments for the B
class, but only one for the A
class.
Typescript won't allow you to do this for this reason.
There are a ton of ways to structure your code to handle this, but here's two ideas.
Make the second parameter optional.
class B extends A {
game(a: string, b?: number): string{
return a + ' ' + b?.toString();
}
}
Now it's safe to call B
instances with only one argument. That means that if we assume that a B
instance as an A
instance, we can call game
with one argument and everything works.
However, if we know for sure it's a B
instance, then we can still pass in that second argument.
Make a new method.
class B extends A {
gameWithTwo(a: string, b: number): string{
return this.game(a) + ' ' + b.toString();
}
}
Here you add a new method to the child class that calls the original method, but has a different signature.
Upvotes: 1