typescript 为什么操作创建者具有类型属性?

kb5ga3dv  于 2022-12-14  发布在  TypeScript
关注(0)|答案(1)|浏览(91)

我正在创建一个接受Actions数组的函数,这种类型只要求它有一个type属性。在为该函数编写测试时,我犯了一个错误,直接传递了Action Creator,而不是调用它的结果,导致测试失败。在我发现错误后,我意识到typescript并没有抱怨,因为BaseActionCreator也有一个type属性,所以对于typescript,如果我将它们中任何一个作为参数传递(这似乎是我不希望发生的),它们是可以互换的。
有什么特别的原因吗?有没有办法防止动作创建者被接受为参数?
您可以在以下网址查看即将推出的产品的示例:https://codesandbox.io/embed/typescript-playground-export-forked-0qjt4k?fontsize=14&hidenavigation=1&theme=dark

import { Action, createAction } from "@reduxjs/toolkit";

function myFunction(actions: Action[]) {
  actions.forEach((action) => console.log(action.type));
}

const customActionCreator = createAction("CUSTOM");

myFunction([customActionCreator()]);
myFunction([customActionCreator]);
f87krz0w

f87krz0w1#

BaseActionCreator(或者在您的情况下,ActionCreatorWithoutPayload)需要type属性来将其自身与其他操作创建者进行比较。
我们可以看到它在.match方法中使用。

actionCreator.match = (action: Action<unknown>): action is PayloadAction =>
    action.type === type

这意味着任何ActionCreatorWithoutPayload都可以赋值给Action,因为它们都有payloadtype属性,但是我们实际上不允许将ActionCreatorWithoutPayload传递给函数。
我们还可以看看ActionCreatorWithoutPayload有什么属性。因为它是一个函数,所以它有call属性,我们可以通过Action{ call?: never }的交集来 “黑名单”

function myFunction(actions: (Action & { call?: never })[]) {
  actions.forEach((action) => console.log(action.type));
}

它给出了我们想要的误差。

myFunction([customActionCreator()]);

myFunction([customActionCreator]);
//          ^^^^^^^^^^^^^^^^^^^ Type 'ActionCreatorWithoutPayload<"CUSTOM">' is 
//                              not assignable to type '{ call?: undefined; }

Playground

相关问题