4

我一直在为 createAction 方法浏览 NgRx Doumentation,如下链接所示: CreateAction 方法的 重载

我无法理解下面这个方法的类型签名,特别是 createAction 方法的返回类型:什么是

() => TypedAction<T>

在这个签名中:

 ActionCreator<T, () => TypedAction<T>>

我没有看到任何参考TypedAction?这是否意味着任何特定动作类型的形状对象?

我在上面的返回类型签名中对 T 的理解是,它是 ActionCreator 函数的泛型类型,它在调用时将返回类型为 T 的 Action。但不确定其他类型参数是否表明它似乎是某个返回TypedAction类型为 T 的函数。想知道一个真实世界的例子。

4

1 回答 1

5

TypedAction是一个通用接口,它通过添加只读type属性来扩展 Action 类型。

export declare interface TypedAction<T extends string> extends Action {
  readonly type: T;
}

ActionCreator<T, () => TypedAction<T>>- 告诉我们我们有一个返回 TypedAction 对象的工厂() => ({ type: T})

让我们定义一个动作创建者:

export const logout = createAction('[Auth] Logout');

createAction函数在 action_creator.ts 中定义。

export function createAction<T extends string>(
  type: T
): ActionCreator<T, () => TypedAction<T>>;

从声明中我们可以看出,createAction它将返回一个函数,该函数又返回一个具有type字符串属性的对象,在我们的例子中为<T extends string>

让我们深入了解一下实际的实现。当您不为操作创建者提供有效负载时,将执行以下代码

export function createAction<T extends string, C extends Creator>(
  type: T,
  config?: { _as: 'props' } | C
): Creator {
...
    case 'empty':
      return defineType(type, () => ({ type }));
...
}

而defineType是:

function defineType(type: string, creator: Creator): Creator {
  return Object.defineProperty(creator, 'type', {
    value: type,
    writable: false,
  });
}

defineType接受类型 ('[Auth] Logout') 和 Creator - () => ({ type })。它返回 Creator 但带有一个新属性type。所以调用logout.typeandlogout().type将返回相同的值 - '[Auth] Logout'

稍后,在 reducer_creator.ts 中,它允许我们提取 ActionCreator 类型(在我们的例子中为“[Auth] Logout”),将其关联到 reducer 函数并执行它

更新:随着问题的答案变得越来越大,我决定写一篇博客文章NgRx Action Creators 是如何工作的

于 2019-11-04T12:17:30.093 回答