本文介绍了您建议如何合并属性相同但值类型不同的接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在ReactJS上使用useReducer,并且我已经定义了几个操作接口来在我的reducer function中使用它们。我看到我使用相同的属性,但有时使用不同的有效负载值。

interface MembersAction {
  type: "JOIN" | "LEAVE";
  payload: string;
}

interface MessagesAction {
  type: "MESSAGE";
  payload: Message;
}

interface ErrorAction {
  type: "ERROR";
  payload: string;
}

interface RoomAction {
  type: "ROOM";
  payload: RoomData;
}

老实说,这感觉有点臃肿,我觉得肯定有更好的方法来实现我正在做的事情。

以下是Reducer函数:

type Action = MembersAction | MessagesAction | RoomAction | ErrorAction;

const reducer = (state: RoomState, action: Action) => {
  switch (action.type) {
    case "JOIN":
      return {
        ...state,
        members: [...state.members, action.payload],
      };
    case "LEAVE":
      return {
        ...state,
        members: state.members.splice(state.members.indexOf(action.payload), 1),
      };
    case "MESSAGE":
      return {
        ...state,
        messages: [...state.messages, action.payload],
      };
    case "ROOM":
      return action.payload;
    case "ERROR":
      return state.error
        ? {
            ...state,
          }
        : {
            ...state,
            error: action.payload,
          };
    default:
      return state;
  }
};

推荐答案

您的代码在我看来很好,在这个playground link中似乎运行良好。

  • 您已正确地将其表示为discriminated union,以便TypeScrip在switch块中正确推断您的payload类型。
  • 您的payload类型在您的不同操作之间不兼容,因此通过多态处理payload不会获得太多好处。
  • 您的Reducer近似于visitor pattern,尽管TypeScrip的结构类型意味着您避免了一些通常与该模式相关联的接口。如果您的Reducer表示的操作本质上是某个Action应该能够对其自身做的,我可以看到重构的价值,这样每个Action都提供一个方法的实现,其工作方式与您的reducer类似,但它接受某些类定义样板而不是switch语句样板。
在仔细考虑这一点时,确定是否更有可能添加需要表达新行为的操作(以便行为应该封装在操作中),还是添加操作大多数或所有新操作的自包含函数(使得行为应该像您一样封装在switch中)。如果不清楚,就别管它了--就我个人而言,我很乐意接受像您这样明确定义的代码。

这篇关于您建议如何合并属性相同但值类型不同的接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 15:50