Hi I'm building a UseContext Provider with typescript. I think I've build it correctly but I've got a litle type error but I can't figure it out.
type SetValue = (value: any) => void;
export interface AppContextInterface {
value: any;
setValue: SetValue;
}
export const ExempleCtx = createContext<AppContextInterface | null>(null);
const CtxProvider = ({ children }: { children: React.ReactNode }) => {
const [value, setValue] = useState<any>(null);
return (
<ExempleCtx.Provider value={{ value, setValue }}>
{children}
</ExempleCtx.Provider>
);
};
export default CtxProvider;
interface Test {
username: any;
}
const defaultState = {
username: "thomas",
};
export const AppContext = createContext<Test>(defaultState);
export function Hooktest() {
return (
<CtxProvider>
<Btn></Btn>
</CtxProvider>
);
}
function Btn() {
const { value, setValue } = useContext(ExempleCtx);
return <div onClick={() => setValue("thomas")}>{value}</div>;
}
I tried typing the useState but it's not comming from their. I think its my createContext that is not correctly type. Thank you for your repplies.
CodePudding user response:
The problem is that ExempleCtx
has type AppContextInterface | null
and you cannot destructure from null.
If you are sure, just let TS know that useContext(ExempleCtx)
will never return null. I think there is no way around it but you have to use type assertion. Use the as
keyword.
const { value, setValue } = useContext(ExempleCtx) as AppContextInterface;
If you do not want to fill your codebase with these then just create a seperate hook and return the val with non-null assertion operator. It tells TS that the value is non-null and non-undefined:
const useExempleCtx = () => {
const val = useContext(ExempleCtx);
return val!;
};
const { value, setValue } = useExempleCtx();
CodePudding user response:
When you first created the context
export const ExempleCtx = createContext<AppContextInterface | null>(null);
, you set his type to AppContextInterface | null
. The context can be null
.
To ignore this warning, you can just add a !
like so
const { value, setValue } = useContext(ExempleCtx!);