Home > Back-end >  typescript type mismatch issue
typescript type mismatch issue

Time:08-18

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?.

  • Related