I have a generic function fetcher which accepts a callback parameter. This callback will be executed in the fetcher function later on (I'm using Vue composables pattern here). Further, these callbacks accepts different parameters as an argument. I've typed fetcher callback that accepts "params" parameter as an union type of possible params. Then I can use this fetcher function and pass callbacks with different parameters.
Code example:
type Param1 = {
a: string;
}
type Param2 = {
a: string;
b: string;
}
type Params = Param1 | Param2
declare function fetcher(func: (params: Params) => void): void
declare function testFunc(obj: Param2): void
fetcher(testFunc)
Typescript error:
Argument of type '(obj: Param2) => void' is not assignable to parameter of type '(params: Params) => void'.
Types of parameters 'obj' and 'params' are incompatible.
Type 'Params' is not assignable to type 'Param2'.
Property 'b' is missing in type 'Param1' but required in type 'Param2'.(2345)
How can I type fetcher function and pass a callback with declared params, like Param1 or Param2 which fetcher can accept?
Params2just always more that Params1? If so just usePrams2in callback signature. Functions that expect less will work typescriptlang.org/play?#code/…Param2 extends Param1but if that's not true in general (e.g., maybeParam2should be{a: number}), then how would thefetcher()implementation know which parameters to pass to it? This is important because while you could potentially rewritefetcher()'s call signature like((x: Param1) => void) | (x: Param2) => void)and even do so programmatically fromParams, such a union of functions would be almost useless in practice.fetcher()needs something like a discriminated union input that lets the implementation know which of these callback types it's getting, so it knows how to call it.