【问题标题】:Typescript Generics constraint not working打字稿泛型约束不起作用
【发布时间】:2018-02-19 18:50:09
【问题描述】:

大家好,我有这个问题

我正在创建一个我只想与约束一起使用的服务

为此我有一个界面

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

我有什么遗漏的吗?还是我的做法不对?

【问题讨论】:

  • 你的样本没有编译,ITemplatingServiceIServiceModelNotFromBase 用作Services 的类型参数,它也是一个类吗?你能把BaseModelNotFromBase 的代码贴出来吗?
  • 啊抱歉,我现在就解决这个问题.. 是的,ITemplatingService 是 IService。所以我有 Base 这只是一个标记,界面应该只适用于扩展 Base ex ModelFromBase .. 但正如你所看到的,我有 ModelNotFromBase 可以使用

标签: typescript


【解决方案1】:

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

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) { }
}

【讨论】:

  • @MCR 编辑了答案,我的意思是 nonstructural 字段是私有的
猜你喜欢
  • 2019-09-23
  • 2021-04-20
  • 2022-11-23
  • 2020-08-03
  • 2018-02-09
  • 1970-01-01
  • 1970-01-01
  • 2021-08-06
  • 2020-07-29
相关资源
最近更新 更多