Exploring the power of TypeScript 3.0 and above, let's take a look at a simple setup involving generic typed variables:
abstract class BaseClass {
public abstract merge<T>(model?: T): T;
}
class MyClass extends BaseClass {
public Value: string;
public merge<MyClass>(model?: MyClass): MyClass {
this.Value += model.Value; // <--Property 'Value' does not exist on type 'MyClass'
return this; // <--Type 'this' is not assignable to type 'MyClass'.
// Type 'MyClass' is not assignable to type 'MyClass'.
// Two different types with this name exist, but they are unrelated.
}
}
After encountering some errors pointed out by the TypeScript compiler that initially seemed confusing, I did some analysis to figure out what went wrong. Here's where things stood after making adjustments:
abstract class BaseClass {
public abstract merge<T>(model?: T): T;
}
class MyClass extends BaseClass {
public Value: string;
/*
Property 'merge' in type 'MyClass' is not assignable to the same property in the base type 'BaseClass'.
Type '(model?: MyClass) => MyClass' is not assignable to type '<T>(model?: T) => T'.
Types of parameters 'model' and 'model' are incompatible.
Type 'T' is not assignable to type 'MyClass'.
*/
public merge(model?: MyClass): MyClass {
this.Value += model.Value;
return this;
}
}
I tried various solutions such as attempting to define T as a type that extends BaseClass, but unfortunately, the issue persisted when using TypeScript versions 2.4+. Interestingly, everything worked smoothly with TypeScript 2.2.1.