I was going through react typescript cheatsheet and one code snippet caught my attention:
export function createCtx<A>(defaultValue: A) {
type UpdateType = Dispatch<SetStateAction<typeof defaultValue>>;
const defaultUpdate: UpdateType = () => defaultValue;
const ctx = createContext({
state: defaultValue,
update: defaultUpdate,
});
function Provider(props: PropsWithChildren<{}>) {
const [state, update] = useState(defaultValue);
return <ctx.Provider value={{ state, update }} {...props} />;
}
return [ctx, Provider] as const; // alternatively, [typeof ctx, typeof Provider]
}
the purpose of this function function is to create a context and provider based on the defaultValue passed to the function.
I have difficulty understanding the first two lines of the function:
type UpdateType = Dispatch<SetStateAction<typeof defaultValue>>;
const defaultUpdate: UpdateType = () => defaultValue;
Dispatch is defined as:
type Dispatch<A> = (value: A) => void;
and SetStateAction as:
type SetStateAction<S> = S | ((prevState: S) => S);
this make () => defaultValue not assignable to type UpdateType, How this can possible.
>Solution :
I let you check this typescript playground to see that there is no problem.
To elaborate, let’s unroll the UpdateType:
type DVT = typeof defaultValue;
type UpdateType = (value: DVT | ((prevState: DVT) => DVT) => void;
And the function () => defaultValue; has a type:
type FunType = () => DVT;
So first let’s consider the return value: void should not accept a return value right? Well not exactly, void does not force a function to not return a value. It’s very common to assign a function that return value to a type with a void return type.
See Assignability of Functions for this and this of course Why are functions returning non-void assignable to function returning void?.
Then the argument value, the function () => defaultValue ignore the arguments so it’s safe to use it an UpdateType type. You could have written (value) => defaultValue, but value would be unused, so TypeScript consider it safe (which is).
See Why are functions with fewer parameters assignable to functions that take more parameters?.