TypeScript编译器与大型继承/扩展链混淆

时间:2016-11-08 11:29:28

标签: generics typescript interface tsc

我有以下(相当复杂的)扩展链。这是我的问题的一个可重复性最小的例子(显然,我的应用程序中的类将具有行为实现)。

export class BaseModel
{
    public someBaseModelMethod(): void { }
}

export class BaseView
{
    public someBaseViewMethod(): void { }
}

export class CollectionView<TChildView extends BaseView, TModel extends BaseModel>
    extends BaseView
{
    public someCollectionViewMethod(): void { }
}

export class ItemView<TModel extends BaseModel>
    extends BaseView
{
    public setItem(model: TModel): void { }
}

export interface IGridView<TChildView extends ItemView<TModel>, TModel extends BaseModel>
    extends CollectionView<TChildView, TModel>
{
    someGridViewMethod(): void;
}

export class GridView<TChildView extends ItemView<TModel>, TModel extends BaseModel>
    extends CollectionView<TChildView, TModel>
    implements IGridView<TChildView, TModel>
{
    public someGridViewMethod(): void { }
}

function bind<TInterface>(key: string, implementation: new (...args: any[]) => TInterface) {
    // do some bindings here
}

bind<IGridView<ItemView<BaseModel>, BaseModel>>("IGridView", GridView);

编译时,我在最后一行的GridView部分(bind语句)出错。错误如下:

TS2345 Argument of type 'typeof GridView' is not assignable to parameter of type 'new (...args: any[]) => IGridView<ItemView<BaseModel>, BaseModel>'.
    Type 'CollectionView<any, any>' is not assignable to type 'IGridView<ItemView<BaseModel>, BaseModel>'.
        Property 'someGridViewMethod' is missing in type 'CollectionView<any, any>'.

正如您所看到的那样,someGridViewMethod期待CollectionView。但是,GridView 延伸 CollectionView,为什么期望在GridView类上找到CollectionView方法?

代码在2.0.3中正确编译,但在1.8.10中没有。

1 个答案:

答案 0 :(得分:1)

这适用于1.8.x2.x

type TypedGridView = { new (...args: any[]): IGridView<ItemView<BaseModel>, BaseModel> };

function bind<TInterface>(key: string, implementation: new (...args: any[]) => TInterface) {
    // do some bindings here
}

bind("IGridView", GridView as TypedGridView);

code in playground

似乎1.8.x编译器无法识别GridView作为构造函数:

IGridView<ItemView<BaseModel>, BaseModel>