【问题标题】: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

【问题讨论】:

    标签: typescript generics typescript-generics


    【解决方案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

    【讨论】:

      猜你喜欢
      • 2022-11-23
      • 2021-04-20
      • 2019-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-09
      相关资源
      最近更新 更多