Illustration:
function useFunction(fn) {
return fn;
}
type Data = {
'/person': { person: any },
'/place': { place: any },
};
function useData<Path extends keyof Data>(
path: Path,
options: {
callback?: (data: Data[Path]) => void,
},
) {}
useData('/person', { callback: ({ person }) => null }); // ok
useData('/person', { callback: ({ place }) => null }); // Property 'place' does not exist on type '{ person: any; }'
useData('/person', { callback: useFunction(({ person }) => null) }); // ok
useData('/person', { callback: useFunction(({ place }) => null) }); // should have error
TS Playground: Link
In this scenario, when using useFunction
, TypeScript was able to automatically infer the type of the callback's argument. However, if useFunction
is not used, this inference is lost.
Surprisingly, by making the callback
property compulsory, TypeScript can infer the type of the argument as shown below:
function useData<Path extends keyof Data>(
path: Path,
options: {
callback: (data: Data[Path]) => void, // <- "?" removed
},
) {}
useData('/person', { callback: useFunction(({ place }) => null) }); // Property 'place' does not exist on type '{ person: any; }'
How can TypeScript deduce the callback's argument type?