Reputation: 273
I have a generic method
abstract run<T> (options: T): void;
And then in the implementation, say I want the type of T to be class B which is in namespace A. TSLint complains if I use
run <A.B> (options: A.B) : void
The error is
Type '<A, B>(options: B) => void' is not assignable to type '<T>(options: T) => void'
It seems that the dot '.' is being read as ',' ? How should I pass the type?
Upvotes: 1
Views: 2801
Reputation: 249476
If a method is generic in a base class it can't be implemented for just one type in the derived class. This would break OOP principles, as you couldn't use the derived class where the base class is expected:
namespace A {
export class B { private x!: string}
}
abstract class Abs {
abstract run<T>(p: T): void;
}
class Impl extends Abs{
run(p: A.B) { } // We get an error here as we should but if this were allowed we would get the error below
}
let a: Abs = new Impl();
a.run(""); // Impl expects A.B, but Abs will let us pass in any T not ok
Note The syntax you use is also wrong, you can only specify concerte types in calls as generic type arguments, you can't use a type in as a type parameter in a function/method declaration. There is no syntax for this because it generally makes no sense as outlined above.
A good option would be to move the generic type parameter to the class instead:
namespace A {
export class B { private x!: string}
}
abstract class Abs<T> {
abstract run(p: T): void;
}
class Impl extends Abs<A.B>{
run(p: A.B) { } // ok now
}
let a: Abs<A.B> = new Impl();
a.run(new A.B()); // type safe
Upvotes: 1