What is wrong with this overload signature? My goal is to use overloaded signatures to create several type-safe versions of an permissively-typed API. The API takes a string channel parameter and a handler callback with an event first parameter and then whatever parameters you want (event, ...args[]) => void.
It seems to me that string can be assigned to unknown, so the overload argument (event: Event, msg: string) => void should work with the implementation argument (event: Event, ...args: unknown[]) => void
function handle(
channel: string,
listener: (event: Event, ...args: any[]) => any
): void { }
export function typedIpcHandle( // ← Works great
channel: "getVersion",
listener: (event: Event) => string
): void;
export function typedIpcHandle( // ← 💥 Error
channel: "notifyUser",
listener: (event: Event, msg: string) => void
): void;
export function typedIpcHandle(
channel: string,
listener: (
event: Event,
...args: unknown[] // ← any[] works, but unknown[] doesn't
) => unknown
): void {
return handle(channel, listener);
}
The second overload signature gives this error: This overload signature is not compatible with its implementation signature.(2394)
This is IPC Handle in Electron, if that is helpful.
contravariant, so althoughstring extends unknown, it is not contravariant, thus it does not work.anyis explicitly acknowledging that you might do something unsafe, while usingunknownis saying that you promise to be safe. And what you're doing is not guaranteed to be safe. You shouldn't assign a value of type(msg: string) => voidto a value of type(...args: unknown[]) => voidbecause the former requires astringinput and someone calling the latter is not required to supply one. Leading to possible runtime errors like this. I'd suggest doing something like this, or just stick withanyinstead ofunknown.