打字稿中具有泛型的子类型约束

Posted

技术标签:

【中文标题】打字稿中具有泛型的子类型约束【英文标题】:Subtype constraints with generics in typescript 【发布时间】:2020-08-03 09:03:18 【问题描述】:

拥有此代码:

export interface IModel 
  id: string;


export interface StatusResponse<
  TModel extends IModel = IModel,
  TResponse = any
> 
  item: TModel;
  response: TResponse;


export class Transport<TItem extends IModel = IModel> 
  save(item: TItem): StatusResponse<TItem> 

    const result: StatusResponse<TItem> = 
      item:  // << error
        id: ""
      ,
      response: 
        stat: "ok"
      
    ;

    return result;
  


save 函数中,我收到了这个错误:

 Type ' id: string; ' is not assignable to type 'TItem'.
  ' id: string; ' is assignable to the constraint of type 'TItem', but 'TItem' could be instantiated with a different subtype of constraint 'IModel'.

令我困惑的是,接口StatusResponse 具有与Transport 的类Transport 相同的约束和默认值TModel TItem 但是,在save 函数中,它们表示为不匹配。

如果我像这样编写save 方法,就没有问题。


  save(item: TItem): StatusResponse 

    const result: StatusResponse = 
      item: 
        id: ""
      ,
      response: 
        stat: "ok"
      
    ;

    return result;
  


请注意,我从 StatusResponse 中删除了泛型类型,因此它采用了默认值。

我不确定这里发生了什么。

Typescript Playground

【问题讨论】:

【参考方案1】:

想一想,如果将上述类与需要额外属性的泛型参数一起使用会发生什么。例如:

new Transport< id: string, additionalProp: string >()

Save 方法会产生缺少 additionalProp 的结果 - 这就是您收到错误的原因。


不确定这在您的情况下是否有意义,但您可以将原始项目传播到响应中以保留类型结构:

export class Transport<TItem extends IModel = IModel> 
  save(item: TItem): StatusResponse<TItem> 

    const result: StatusResponse<TItem> = 
      item: 
        ...item,
        id: ""
      ,
      response: 
        stat: "ok"
      
    ;

    return result;
  

Playground

【讨论】:

以上是关于打字稿中具有泛型的子类型约束的主要内容,如果未能解决你的问题,请参考以下文章

unity的C#学习——泛型的创建与继承泛型集合类泛型中的约束和反射

如何将方法的泛型类型限制为打字稿中的对象?

具有泛型的Swift函数,其中约束是自身符合的协议

请教一个unity有关于泛型参数的问题

Java8基础知识泛型的约束与局限性

C#的泛型的类型参数可以有带参数的构造函数的约束方式吗?