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.
CodePudding user response:
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 a 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?.