Typescript Generics约束不起作用

时间:2018-02-19 10:30:00

标签: typescript

大家好,我有这个问题

我正在创建一个我只想使用约束

的服务

为此我有一个界面

abstract class Base {

}


class ModelFromBase extends Base {

}

interface IService<T extends Base> { 
   doSomething(model: T); 
}

和实现接口的这个类

class ModelNotFromBase {

}

class Services<ModelNotFromBase>  implements IService<ModelNotFromBase> {
       doSomething(model: T) {} 
}

问题是ModelNotFromBase没有扩展Base(顾名思义),并且TS编译器不会尖叫它。

当我创建一个IService实例时

private _instance: IService<ModelNotFromBase>;

同样的问题,我的意思是我可以提供任何东西。

这是什么问题,

如文档所示,您可以使用约束

https://www.typescriptlang.org/docs/handbook/generics.html

有什么东西我错过了吗?或者我不是以正确的方式做到这一点?

1 个答案:

答案 0 :(得分:2)

根据BaseModelNotFromBase的定义方式,这可能是预期的行为。在确定类型兼容性时,typescript使用结构兼容性。这意味着这两个类彼此完全兼容:

class Base {
    name: string;
}

class ModelNotFromBase {
    name: string;
}
var b : Base = new ModelNotFromBase(); // Works fine 

如果类/接口Base为空(class Base { }),那么约束并没有真正约束任何东西,因为任何其他类型都可以分配这种类型的变量

class Base { }
var d : Base = 0;
var d2: Base = "";

如果你想避免结构类型,你可以在Base类上定义一个私有属性(不必使用它只需要存在)然后只能通过类来满足约束继承Base

class Base { 
    private nonstructural: true;
}
class ModelNotFromBase { }

interface ITemplatingService<T extends Base> {
    doSomething(model: T);
}

export class Services<T extends Base> implements ITemplatingService<T> {
    doSomething(model: T) { }
}

var  _instance: ITemplatingService<ModelNotFromBase>; //error 
export class OtherServices implements ITemplatingService<ModelNotFromBase> { // also error
    doSomething(model: ModelNotFromBase) { }
}