EDIT
After adding generic types and avoiding function union, here's what I have. Same exact problem, though.
const fn1: ((obj: { A: string }) => string) = (input) => { return input.A }
const fn2: ((obj: { B: number }) => number) = (input) => { return input.B }
const fns = { fn1, fn2, }
type allowedFns = keyof typeof fns // 'fn1' | 'fn2'
const caller = <fnName extends allowedFns>(fn: (typeof fns)[fnName], input: Parameters<(typeof fns)[fnName]>[0]) => {
fn(input)
}
Original post
Here is a very basic example I came up with. I want caller
to take in fn
and input
and call fn(input)
. fn
is only allowed to be of a type in allowedFns
.
type allowedFns = ((obj: { A: string }) => any) | ((obj: { B: number }) => any)
const caller = (fn: allowedFns, input: { A: string } | { B: number }) => {
return fn(input) /* ERROR: Argument of type '{ A: string; } | { B: number; }'
is not assignable to parameter of type '{ A: string; } & { B: number; }' */
}
I'm getting an error (see comment). fnType is being incorrectly typed! The following is how it's currently being typed:
(parameter) fn: (obj: { A: string; } & { B: number; }) => any
But it should really be typed as follows:
(parameter) fn: (obj: { A: string; } | { B: number; }) => any
Why does the |
of functions combine their inputs like an &
??? And is there a fix?