(This post is originally from Retsam on the TypeScript Discord server).
There's a particular pattern that is safe but hard for the Typescript compiler to handle, which I call the "correspondence problem":
const functionsWithArguments = [
{ func: (arg: string) => {}, arg: "foo" },
{ func: (arg: number) => {}, arg: 0 },
];
for (const { func, arg } of functionsWithArguments) {
func(arg);
// ^^^
// Argument of type 'string | number' is not assignable to parameter of type 'never'.
// Type 'string' is not assignable to type 'never'.
}
The problem is that func
is typed as (x: string) => void | (x: number) => void
and arg
is string | number
, but the compiler can't prove that they "correspond": that, for example, arg
is only a string when func
accepts strings.
As far as the type are concerned, arg
could be number
, and func
could be (arg: string) => void, and that would be a type-error. It's easy for us to see that that won't happen, but that requires understanding the program at a higher-level than the level the compiler operates.
Depending on the specifics there's sometimes clever fixes, but usually I recommend using a type assertion and ignoring the issue:
func(arg as never);