简体   繁体   English

通用类的TypeScript数组

[英]TypeScript array of generic classes

I'm having trouble getting the TypeScript compiler to not give me grief. 我无法让TypeScript编译器给我带来麻烦。 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 . 所有这些都将在同一基础UnitView基础上UnitView For some reason I get an error if my TitleView does not also accept generics, but I get no errors if it does. 由于某种原因,如果我的TitleView也不接受泛型,则会出现错误,但如果我不接受泛型,则不会出错。

I'm not understanding why TitleView would need to accept generics because it passes the Model type explicitly to the UnitView . 我不明白为什么TitleView需要接受泛型,因为它将Model类型显式传递给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 如果您要在其中测试, 这里是指向TypeScript游乐场的直接链接

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 . TileView 不可分配给typeof UnitView The key reason being that the type of T (a generic) are not compatible with {} . 关键原因是T (泛型)的类型与{}不兼容。

This is similar to the further simplified example shown below: 这类似于下面显示的进一步简化的示例:

class Foo<T> { 
    model: T
}
class Bar{
    model: {}
}

const example2: typeof Foo = Bar; // ERROR 

TLDR TLDR

Generics T and instances (even {} ) are not compatible for assignment. 泛型T和实例(甚至{} )不兼容分配。 This is by design. 这是设计使然。

More 更多

The only way to stay compatible is the preserve the generic as well eg 保持兼容性的唯一方法就是保留generic ,例如

class Foo<T> { 
    model: T
}
class Bar<T>{
    model: T
}

const example3: typeof Foo = Bar; // Okay 

To complement basarat's answer, here's a working declaration: 为了补充巴萨拉特的回答,这是一个可行的声明:

private ViewClasses: (new (...args: any[]) => UnitView<{}>)[] = [
    TitleView
]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM