Javascript 如何定义Redux操作的流类型?

Javascript 如何定义Redux操作的流类型?,javascript,redux,flowtype,Javascript,Redux,Flowtype,我正在研究使用Flow键入Redux操作的方法。使用以下定义,它在action creator和reducer中部分工作。“自动完成”将所有4个操作作为操作的可能值。在两个位置键入 // @flow type ModuleActionTypes1 = 'moduleOne/ACTION_ONE' | 'moduleOne/ACTION_TWO'; type ModuleActionTypes2 = 'moduleTwo/ACTION_ONE' | 'moduleTwo/ACTION_TWO';

我正在研究使用Flow键入Redux操作的方法。使用以下定义,它在action creator和reducer中部分工作。“自动完成”将所有4个操作作为
操作的可能值。在两个位置键入

// @flow
type ModuleActionTypes1 = 'moduleOne/ACTION_ONE' | 'moduleOne/ACTION_TWO';
type ModuleActionTypes2 = 'moduleTwo/ACTION_ONE' | 'moduleTwo/ACTION_TWO';

type ActionTypes = ModuleActionTypes1 | ModuleActionTypes2;

type Action<T> = {
  type: ActionTypes,
  payload: T
};

type Payload = {
  url: string
};

const actionCreator = (url: string): Action<Payload> => {
  return {
    type: 'moduleOne/ACTION_ONE',
    payload: {
      url: url
    }
  };
};

const reducer = (state: string, action: Action<Payload>): string => {

  if(action.type === 'wrong') {
    // action.type cannot be this 
  }

  switch (action.type) {
    case 'moduleOne/ACTION_ONE':
    case 'wrong': // action type cannot be this
      const { url } = action.payload;
      return url;
    default:
      return state;
  }
};
/@flow
类型ModuleActionTypes1='moduleOne/ACTION_ONE'|'moduleOne/ACTION_TWO';
类型ModuleActionTypes2='ModuleWO/ACTION_ONE'|'ModuleWO/ACTION_TWO';
类型ActionTypes=ModuleActionTypes1 | ModuleActionTypes2;
类型操作={
类型:ActionType,
有效载荷:T
};
类型有效载荷={
url:string
};
const actionCreator=(url:string):Action=>{
返回{
键入:“模块一/动作一”,
有效载荷:{
url:url
}
};
};
const reducer=(状态:string,操作:action):string=>{
如果(action.type==='错误'){
//action.type不能是此类型
}
开关(动作类型){
案例“模块一/行动一”:
案例“错误”://操作类型不能为此
const{url}=action.payload;
返回url;
违约:
返回状态;
}
};
它几乎满足了我的需求。有两个主要问题:

  • 开关盒不必是
    action.type
    类型,因此打字错误可能会漏掉。这表明我应该坚持使用字符串常量

  • 当我从“../moduleOne”导入类型{ModuleActionTypes1}时(而不是在同一个文件中定义它进行测试)autocomplete停止工作,但flow在命令行上不报告任何错误。所有文件都包含@flow注释


  • 有更好的方法吗?

    因此,这与您的问题有点不同,但我建议您的做法有点不同。现在,您的操作类型表示任何负载都可以属于任何操作。如果您使用类型仅定义允许的状态,则流将更有帮助

    我不知道你的行为是什么,所以这里有一个随机的例子:

    type CreatePerson = { type: 'create-person', person: Person };
    type DestroyPerson = { type: 'destroy-person', personId: number };
    type ChangePersonName = { type: 'change-name', personId: number, name: string }
    type PersonActions = CreatePerson | DestroyPerson | ChangePersonName
    

    以这种方式设置它有助于确保每个Redux操作都具有正确类型的正确数据。在减速机中,您仍然可以执行开关/if on
    操作。键入
    选择要使用的案例。但现在,通过按字符串选择类型,Flow还确切地知道操作上存在什么类型的数据。这可以让您避免流无法进行类型检查的强制转换或不安全的破坏结构。

    因此,这与您的问题有点不同,但我建议您以不同的方式执行此操作。现在,您的操作类型表示任何负载都可以属于任何操作。如果您使用类型仅定义允许的状态,则流将更有帮助

    我不知道你的行为是什么,所以这里有一个随机的例子:

    type CreatePerson = { type: 'create-person', person: Person };
    type DestroyPerson = { type: 'destroy-person', personId: number };
    type ChangePersonName = { type: 'change-name', personId: number, name: string }
    type PersonActions = CreatePerson | DestroyPerson | ChangePersonName
    

    以这种方式设置它有助于确保每个Redux操作都具有正确类型的正确数据。在减速机中,您仍然可以执行开关/if on
    操作。键入
    选择要使用的案例。但现在,通过按字符串选择类型,Flow还确切地知道操作上存在什么类型的数据。这可以避免流无法进行类型检查的强制转换或不安全的破坏结构。

    感谢您的响应。虽然这看起来有点简单,但它仍然存在类似的问题。如果我在switch案例中得到action.type correct,则有效负载被正确键入,错误被突出显示。如果我键入action.type,有效负载将被键入为
    any
    ,并且不会报告任何错误。这不如只使用字符串常量。我的目标是了解一个reducer正在检查一个不存在的
    操作。type
    很可能是错误的。我注意到这段代码按预期工作:
    type AorB='a'|'b';const reducer=(state:string,action:AorB)=>{if(action=='error'){//action.type不能是this}所以它一定是包装对象上的一个属性,可以删除枚举检查?是的,看起来就是这样。您的字符串版本可以正常工作,但除了使用具有type属性的对象之外,其他情况都可以:
    typeaorb={type:'a'}{type:'b'};const reducer=(state:string,action:AorB)=>{if(action.type==='error'){}感谢您的回复。虽然这看起来有点简单,但它仍然存在类似的问题。如果我在switch案例中得到action.type correct,则有效负载被正确键入,错误被突出显示。如果我键入action.type,有效负载将被键入为
    any
    ,并且不会报告任何错误。这不如只使用字符串常量。我的目标是了解一个reducer正在检查一个不存在的
    操作。type
    很可能是错误的。我注意到这段代码按预期工作:
    type AorB='a'|'b';const reducer=(state:string,action:AorB)=>{if(action=='error'){//action.type不能是this}所以它一定是包装对象上的一个属性,可以删除枚举检查?是的,看起来就是这样。您的字符串版本可以正常工作,但除了使用具有type属性的对象之外,其他情况都可以:
    typeaorb={type:'a'}{type:'b'};const reducer=(state:string,action:AorB)=>{if(action.type==='error'){}