如何从打字稿中的联合选项访问属性?

How to access properties from same option of union in typescript?

我有以下示例代码:

type actionT =
  | {
      name: "action1";
      method: (params: { x: number }) => void;
      params: { x: number };
    }
  | {
      name: "action2";
      method: (params: { y: string }) => void;
      params: { y: string };
    };

const x: actionT = {
  name: "action1",
  method: (params) => {
    console.log("Got", params.x);
  },
  params: { x: 12 },
};

const y: actionT = {
  name: "action2",
  method: (params) => {
    console.log("Got", params.y);
  },
  params: { y: "hi" },
};

const run_action_1 = (action: actionT) => {
  switch (action.name) {
    case "action1": {
      action.method(action.params);
      break;
    }
    case "action2": {
      action.method(action.params);
      break;
    }
  }
};

const run_action_2 = (action: actionT) => {
  action.method(action.params); // Typescript Error
};

run_action_1(x); // Works
run_action_1(y); // Works
run_action_2(x); // Does not work
run_action_2(x); // Does not work

我明白为什么它不起作用。但是,我正在寻找一种方法来使其工作,而不是将其包装在具有相同函数调用的开关盒中。那是因为在我的实际代码中我有很多动作。

我看到的错误是:

Argument of type '{ x: number; } | { y: string; }' is not assignable to parameter of type '{ x: number; } & { y: string; }'.
  Type '{ x: number; }' is not assignable to type '{ x: number; } & { y: string; }'.
    Property 'y' is missing in type '{ x: number; }' but required in type '{ y: string; }'.

通用的不能满足您的需求吗?

type actionT<T = any> = {
  name: "action";
  method: (params: T) => void;
  params: T;
}

const x: actionT<{ x: number }> = {
  name: "action",
  method: (params) => {
    console.log("Got", params.x);
  },
  params: { x: 12 },
};

const y: actionT<{ y: string }> = {
  name: "action",
  method: (params) => {
    console.log("Got", params.y);
  },
  params: { y: "hi" },
};

const run_action_2 = (action: actionT) => {
  action.method(action.params); 
};

run_action_2(x); 
run_action_2(x); 

Playground