Как исправить свойство «incrementCount» не существует для типа «ContextType | неопределенный'

Я пытаюсь абстрагироваться от логики useContext и useReducer, чтобы не повторять код всякий раз, когда я создаю новый контекст, но я столкнулся с некоторыми проблемами, когда я пытался сильно ввести createContext с помощью typescript.

С помощью этой функции я автоматизирую создание контекста:

import React, { createContext, ReactElement, useReducer } from 'react';

type ProviderProps = {
    children: ReactElement;
};

type ActionType = {
  type: string;
    payload?: any;
};

export default function <StateType>(
    reducer: (state: StateType, action: ActionType) => StateType,
    actions: any,
    initialState: StateType,
) {
    type ContextType = {
        state: StateType;
        actions:{
            [k: string]: Function;
        }
    };
    const Context = React.createContext<ContextType | undefined>(undefined);

    const Provider = ({ children }: ProviderProps) => {
        const [state, dispatch] = useReducer(reducer, initialState);

        const boundActions: any = {};

        for (let key in actions) {
            boundActions[key] = actions[key](dispatch);
        }
        return (
            <Context.Provider value={{ state, actions:{
                ...boundActions
            } }}>
                {children}
            </Context.Provider>
        );
    };

    return { Context, Provider };
}

Пример создания контекста:

import createDataContext from './createDataContext';
import { INCRASE_COUNT, DECRASE_COUNT } from './ActionTypes';

type ActionType = {
    type: string;
    payload?: any;
};

type StateType = {
    count: number;
};

const reducer = (state: StateType, action: ActionType) => {
    switch (action.type) {
        case INCRASE_COUNT:
            return { count: state.count + 1 };
        case DECRASE_COUNT:
            return { count: state.count - 1 };
        default:
            return state;
    }
};

const incrementCount = (dispatch: React.Dispatch<any>) => {
    return () => {
        dispatch({ type: INCRASE_COUNT });
    };
};

const decrementCount = (dispatch: React.Dispatch<any>) => {
    return () => {
        dispatch({ type: DECRASE_COUNT });
    };
};

export const { Context, Provider } = createDataContext<StateType>(
    reducer,
    {
        incrementCount,
        decrementCount,
    },
    { count: 69 },
);

Когда я его использую:

import { Context as ExampleContext } from '../context/ExampleContext';

const { state, actions } = useContext(
    ExampleContext,
);

он подчеркивает состояние и действия красной линией и говорит: Свойство «состояние, действия» не существует для типа «ContextType | неопределенный'

Что я сделал не так, есть что-то, что я пропустил?

PLZZZZZZ ПОМОГИТЕ МНЕ.


person Fitim Zenuni    schedule 06.01.2021    source источник


Ответы (1)


Вы получаете сообщение об ошибке, поскольку вы указали тип контекста как ContextType | undefined, а undefined не имеет свойств state и actions. Вместо передачи undefined в createContext вы можете реорганизовать свой код следующим образом:

export default function <StateType>(
    reducer: (state: StateType, action: ActionType) => StateType,
    actions: any,
    initialState: StateType,
) {
    type ContextType = {
        state: StateType;
        actions: typeof actions;
    };
    
    const Context = React.createContext<ContextType>({
      state: initialState,
      actions,
    });
    
    ...

    return { Context, Provider };
}

person oozywaters    schedule 06.01.2021
comment
Нет, сэр, это не сработает, потому что 'state' не всегда будет {count: 0}, это может быть что угодно, поэтому я поставил StateType как общий, поэтому тип состояния может быть динамическим - person Fitim Zenuni; 06.01.2021
comment
Тогда почему бы тебе не передать initialState вместо count: 0? Исправил мой ответ, пожалуйста, проверьте его. - person oozywaters; 06.01.2021
comment
я пробовал это, и это сработало const Context = React.createContext ‹ContextType› ({state: initialState, actions,}); THNX очень много - person Fitim Zenuni; 06.01.2021