联合类型调度回调

Posted

技术标签:

【中文标题】联合类型调度回调【英文标题】:Union type dispatch callback 【发布时间】:2021-11-19 03:19:52 【问题描述】:

我正在尝试创建一个通用函数,该函数将用于创建回调操作。 但我不确定在这种情况下如何处理联合类型。 该函数将收到type,如果需要,回调将收到payload。 如果需要有效负载,and 函数将返回带有字段 typepayload 的对象。

我声明的接口:

enum ActionTypes 
    CREATE_GAME = 'CREATE_GAME',
    GET_GAME_INFO = 'GET_GAME_INFO',
    PARTICIPANT_JOIN = 'PARTICIPANT_JOIN',


interface CreateGame 
    type: ActionTypes.CREATE_GAME;


interface GameInfoPayload 
    gameid: number,
    participants: [],
    phase: string,
    activated: boolean


interface GetGameInfo 
    type: ActionTypes.GET_GAME_INFO;
    payload: GameInfoPayload;


interface ParticipantJoin 
    type: ActionTypes.PARTICIPANT_JOIN;
    payload: boolean;


type GameAction = CreateGame |
                  GetGameInfo |
                  ParticipantJoin;

type PayloadGameAction = Extract<GameAction, payload: unknown>

我正在尝试创建的回调:

const buildAction = (action:ActionTypes) => 
    return (payload:PayloadGameAction['payload']):GameAction => 
        return 
            type: action,
            payload: payload
        
    


const createGame = buildAction(ActionTypes.CREATE_GAME);
const getGameInfo = buildAction(ActionTypes.GET_GAME_INFO);
const participantJoin = buildAction(ActionTypes.PARTICIPANT_JOIN);

最后产生的错误:

Type 'boolean | GameInfoPayload' is not assignable to type 'boolean'.
  Type 'GameInfoPayload' is not assignable to type 'boolean'.

很高兴得到任何帮助。

【问题讨论】:

提醒一下:我们不再推荐使用“联合类型”样式,因为它是大量的额外代码,没有任何好处。 (请参阅phryneas.de/redux-typescript-no-discriminating-union)请改用官方的 Redux Toolkit,这是官方推荐编写 any Redux 代码已有两年多的时间了,它会为您处理几乎所有的 TypeScript 类型。 好的,这就是我要找的 【参考方案1】:

你可以试试generic types

enum ActionTypes 
    CREATE_GAME = 'CREATE_GAME',
    GET_GAME_INFO = 'GET_GAME_INFO',
    PARTICIPANT_JOIN = 'PARTICIPANT_JOIN',


interface GameInfoPayload 
    gameid: number,
    participants: [],
    phase: string,
    activated: boolean


interface CreateGame 
    type: ActionTypes.CREATE_GAME;
    // notice payload here
    payload: undefined


interface GetGameInfo 
    type: ActionTypes.GET_GAME_INFO;
    payload: GameInfoPayload;


interface ParticipantJoin 
    type: ActionTypes.PARTICIPANT_JOIN;
    payload: boolean;


type GameAction =
    | CreateGame
    | GetGameInfo
    | ParticipantJoin

type MathingGameActions<T extends ActionTypes> = Extract<GameAction,  type: T >

const buildAction = <T extends ActionTypes = ActionTypes, K extends 
MathingGameActions<T> = MathingGameActions<T>>(action: T) =>
    (payload: K['payload']): K => 
        const result = 
            type: action
        
        // prepare result here
        return result as unknown as K
    

const createGame = buildAction(ActionTypes.CREATE_GAME)
const getGameInfo = buildAction(ActionTypes.GET_GAME_INFO)
const participantJoin = buildAction(ActionTypes.PARTICIPANT_JOIN)

其他选项是function overload, 也许this 会有所帮助

【讨论】:

太好了,谢谢你的提示。我想知道不添加payload: undefinedCreateGame接口可以解决吗?

以上是关于联合类型调度回调的主要内容,如果未能解决你的问题,请参考以下文章

函数的打字稿联合/交集类型

在侦听器回调后调用操作并且...无法在调度中间调度?

是否可以在 React Hooks 中对 useReducer 的调度进行回调?

调度程序没有在开玩笑的单元测试中注册回调

Vue js 2 - 在组件中调度的操作的回调函数

React Hook - 无法在子组件 onComplete 回调中调用父组件调度