Reputation: 1782
I'm having trouble getting the TypeScript compiler to not give me grief. I have a controller which has an array of classes, NOT the instance of the class, but the class itself. All of these will extend off of the same base, UnitView
. For some reason I get an error if my TitleView
does not also accept generics, but I get no errors if it does.
I'm not understanding why TitleView
would need to accept generics because it passes the Model type explicitly to the UnitView
. Can anyone explain or see anything that I'm doing wrong?
Code:
class Model { }
class View<TModel extends Model> {
private model: TModel;
}
class UnitView<TModel extends Model> extends View<TModel> { }
class TitleView extends UnitView<Model> { }
class Controller {
private ViewClass: typeof UnitView;
private ViewClasses: typeof UnitView[] = [
TitleView
]
}
And here is a direct link to TypeScript playground if you want to test it there
Upvotes: 0
Views: 2845
Reputation: 276199
The error has nothing to do with arrays. Here is a minimal reproduction of your bug:
class View<TModel> {
model: TModel;
}
class UnitView<TModel> extends View<TModel> { }
class TitleView extends UnitView<{}> { }
const example1: typeof UnitView = TitleView; // ERROR
TileView
is not assignable to typeof UnitView
. The key reason being that the type of T
(a generic) are not compatible with {}
.
This is similar to the further simplified example shown below:
class Foo<T> {
model: T
}
class Bar{
model: {}
}
const example2: typeof Foo = Bar; // ERROR
Generics T
and instances (even {}
) are not compatible for assignment. This is by design.
The only way to stay compatible is the preserve the generic
as well e.g.
class Foo<T> {
model: T
}
class Bar<T>{
model: T
}
const example3: typeof Foo = Bar; // Okay
Upvotes: 2
Reputation: 220904
To complement basarat's answer, here's a working declaration:
private ViewClasses: (new (...args: any[]) => UnitView<{}>)[] = [
TitleView
]
Upvotes: 0