I am currently utilizing TypeScript for my coding projects, and I have observed that it can allow the production of non-type-safe code. Despite implementing all the "strict" options available to me, the behavior I am experiencing goes against the principle of "Inheritance implies subtyping". This issue has been discussed in various platforms, such as:
https://stackoverflow.com/questions/50729485/override-method-with-different-argument-types-in-extended-class-typescript
One specific piece of code that does not raise any type errors is as follows:
abstract class A {
abstract do(x: number | string): number;
}
class B extends A {
override do(x: number): number {
return x;
}
}
const a: A = new B();
const x: number = a.do("dupa");
console.log(x);
Instead of receiving an expected error message like:
Error:(7, 14) TS2416: Property 'do' in type 'B' is not assignable to the same property in base type 'A'.
Type '(x: number) => number' is not assignable to type '(x: string | number) => number'.
Types of parameters 'x' and 'x' are incompatible.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
The output actually displays "dupa" in the console.
In attempt to troubleshoot this issue, I tried switching types (X, Y) from (number, string) to different pairs under the assumption that there might be implicit casting involved. However, even with pairs of arbitrary or non-assignable types X and Y, or with some combination where X and Y=null (while working with strictNullChecks), I encountered the same outcome.
Furthermore, I was able to deliberately create a type error
Type 'string | number' is not assignable to type 'number'. Type 'string' is not assignable to type 'number'.
. Hence, in general, such assignments should not be permitted.
It appears that this behavior could potentially be considered as a "feature rather than a bug", as indicated in: https://github.com/microsoft/TypeScript/issues/22156
Thus, I am now seeking to rephrase the inquiry:
Is there a workaround available that would prompt the TypeScript type checker to detect the absence of contravariance in parameter types within overridden methods?