Search code examples
reactjstypescriptreact-reduxuse-reduceruse-context

Trying to convert into typescript..cant figure out how to make action types and payload..i am using useContext and use Reducer


Trying to convert into typescript..cant figure out how to make action types and payload..i am using useContext and use Reducer i basically want my action to get types from the key of ./types that is provided and laso figure out the way to provide pylaoad this is my state

import React, { useReducer } from "react"
import AlertContext from "./AlertContext"
import { SHOW_ALERT,REMOVE_ALERT } from "../Types"
import AlertReducer from "./AlertReducer"
import { IAlertState } from "../IAlertState"


export interface typealert{
 variant : string,
text: string,
}
const AlertState = (props : any) =>{

const initialState :IAlertState = {
    alert:{
        variant :'',
        text :''
    }
}

const [state,dispatch] = useReducer(AlertReducer,initialState)

const showAlert =(variant : string,text : string) =>{
    dispatch({type:SHOW_ALERT,payload:{variant,text}})
    setTimeout(()=>{
        setAlert({variant:'',text:''})
    },2000)
}

const setAlert =(alert : typealert) => dispatch({type :REMOVE_ALERT,payload:null})

return(
    <AlertContext.Provider value={{
        alert:state.alert,
        showAlert
    }}>
        {props.children}
    </AlertContext.Provider>
)

}

export default AlertState

this is my reducer

import React from "react"
import { SHOW_ALERT,REMOVE_ALERT } from "../Types"
import { IAlertState } from "../IAlertState"

export interface IActionTypes{
type : any,
payload : any
}

export default (state : IAlertState ,action : IActionTypes) =>{
switch(action.type)
{
    case SHOW_ALERT:
    return{
        ...state,
        alert:{
            variant : action.payload["variant"],
            text:action.payload["text"]
        }
    }
    case REMOVE_ALERT:
        return{
            ...state,
            alert:{
                variant: '',
                text:''
            }
        }
default : return state
}

}

in this the action type i have provided is of any but i want it of type that is coming from ./types file here

export const SEARCH_USERS = 'SEARCH_USERS'
export const GET_USER ='GET_USER'
export const GET_REPOS = 'GET_REPOS'
export const CLEAR_USERS ='CLEAR_USERS'
export const SHOW_ALERT ='SHOW_ALERT'
export const SET_LOADING ='SET_LOADING'
export const USER_LOADING ='USER_LOADING'
export const REMOVE_ALERT ='REMOVE_ALERT'

Solution

  • type ActionTypes =
      | {
          type: SEARCH_USERS;
          payload: IAlertState["alert"];
        }
      | {
          type: REMOVE_ALERT;
          payload: void;
        }
    
      | ....
    
    

    use union types to model your payload & type, since type is a natural tag to discriminate the union type, your code will get well-typed and proper narrowing