Reputation: 319
In the return of useUser()
function, I keep getting this typescript error.
Type '{}' is missing the following properties from type 'IUseUser': userState, dispatchUserContext
import { useReducer, useContext, createContext, FunctionComponent } from 'react';
export interface EditProfileFields {
phone: string;
city: string;
description: string;
startDate: string;
endDate: string;
priceRate: string;
}
export interface IUserContext extends EditProfileFields {
coverImg: string;
profileImg: string;
isDogSitter: boolean;
isAvailable: boolean;
}
type Action =
| { type: 'UPLOAD_PROFILE'; profileImg: string }
| { type: 'UPLOAD_BACKGROUND'; coverImg: string }
| { type: 'EMPTY_IMAGES' }
| { type: 'SET_IS_DOG_SITTER' }
| { type: 'UPDATE_EDIT_PROFILE_FIELDS'; fields: EditProfileFields };
type Dispatch = (action: Action) => void;
export interface IUseUser {
userState: IUserContext;
dispatchUserContext: Dispatch;
}
const userReducer = (state: IUserContext, action: Action) => {
switch (action.type) {
case 'UPLOAD_PROFILE':
return { ...state, profileImg: action.profileImg };
case 'UPLOAD_BACKGROUND':
return { ...state, coverImg: action.coverImg };
case 'EMPTY_IMAGES':
return { ...state, coverImg: '', profileImg: '' };
case 'SET_IS_DOG_SITTER':
return { ...state, isDogSitter: true };
case 'UPDATE_EDIT_PROFILE_FIELDS':
const { startDate, endDate, ...otherFields } = action.fields;
return {
...state,
startDate: startDate !== null ? startDate.substring(0, 10) : '',
endDate: endDate !== null ? endDate.substring(0, 10) : '',
...otherFields,
};
default:
throw new Error();
}
};
const UserContext = createContext({});
const UserProvider: FunctionComponent = ({ children }): JSX.Element => {
const [userState, dispatchUserContext] = useReducer(userReducer, {
coverImg: '',
profileImg: '',
isDogSitter: false,
isAvailable: false,
phone: '',
city: '',
description: '',
startDate: '',
endDate: '',
priceRate: '',
});
return <UserContext.Provider value={{ userState, dispatchUserContext }}>{children}</UserContext.Provider>;
};
function useUser(): IUseUser {
const context = useContext(UserContext);
if (context === undefined) {
throw new Error('useUser must be used within a UserProvider');
}
return context;
}
export { UserProvider, useUser };
Upvotes: 3
Views: 3009
Reputation: 6059
The simple solution to make keys of IUseUser
optional.
export interface IUseUser {
userState?: IUserContext;
dispatchUserContext?: Dispatch;
}
But why it is saying as empty {}? The answer is that you are creating a context with an empty object value. So, your default value is an empty object. You need to give default values to that context. Then you don't need to give optional keys.
const UserContext = createContext<IUseUser>({
userState: {
coverImg: '',
profileImg: '',
isDogSitter: false,
isAvailable: false,
phone: '',
city: '',
description: '',
startDate: '',
endDate: '',
priceRate: '',
},
dispatchUserContext: (action: Action) => {},
});
Don't pass an empty object as a default value to your context. You can either pass undefined or value.
According to the official documentation of react,
"The defaultValue argument is only used when a component does not have a matching Provider above it in the tree. This can be helpful for testing components in isolation without wrapping them. Note: passing undefined as a Provider value does not cause consuming components to use defaultValue."
If you want to give undefined value to your context then in typescript you can create a context like this,
const UserContext = createContext<IUseUser | undefined>(undefined);
Upvotes: 3