首页 > 解决方案 > 如何正确使用带有 ngrx 操作的泛型

问题描述

我正在开发一个使用 NGRX 商店的 Angular 7 应用程序。我们有很多实体,几乎每个实体都有一个专用的列表视图。我想尝试使用 NGRX 存储的泛型,因此我不需要编写几乎相同的选择器、动作、reducers 等。我从动作开始并创建了一个函数,它将返回一组它们,但我无法让它工作.

    // For type safety
    enum AddTypeNames {
      ADD_REQUEST = 'AddRequestAction',
      ADD_SUCCESS = 'AddSuccessAction',
      ADD_FAILURE = 'AddFailureAction',
    }
    // Creates an object literal with a string key and Action as the value
    function createAddActions<T>(featureName: string): { [key in AddTypeNames]: Action } {
      class AddRequestAction implements Action {
        readonly type = `[${featureName}] Add request`;
        constructor(payload: { entity: T }) { }
      }
      class AddSuccessAction implements Action {
        readonly type =  `[${featureName}] Add success`;
        constructor(payload: { entity: T }) { }
      }
      class AddFailureAction implements Action {
        readonly type =  `[${featureName}] Add error`;
        constructor(payload: { error: HttpErrorResponse }) { }
      }
      return {
        AddRequestAction,
        AddSuccessAction,
        AddFailureAction,
      };
    }

但它在编辑器中显示错误:

(property) AddRequestAction: Action
Property 'type' is missing in type 'typeof AddRequestAction' but required in type 'Action'.ts(2741)

我不知道这个错误的真正含义是什么,因为很明显我在课堂上确实有这种类型......我是否以正确的方式这样做?我需要做什么来创建具有泛型类型的操作?尽可能多地使用泛型实际上是否被认为是一种好习惯?

标签: typescriptngrx

解决方案


存在编译错误,因为您声明createAddActions将返回 dict od Action { [key in AddTypeNames]: Action }。但是这种语法意味着类 Action 实例的对象,而不是类。

因此,您告诉 TS 您的返回对象值包含属性“类型”,您的类没有静态属性type

如果要声明函数的结果是带有类的对象(而不是它的实例,请使用以下语法:{ new (...args): Action }.

所以:

function createAddActions<T>(featureName: string): { [key in AddTypeNames]: { new (...args): Action } } {

不会抛出编译错误。

操场


推荐阅读