4

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.

Typescript Playground

4
  • 1
    TS function arguments arecontravariant, so although string extends unknown, it is not contravariant, thus it does not work. Commented Jan 21, 2022 at 20:24
  • Using any is explicitly acknowledging that you might do something unsafe, while using unknown is 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) => void to a value of type (...args: unknown[]) => void because the former requires a string input 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 with any instead of unknown. Commented Jan 21, 2022 at 20:27
  • Please review this question and this question and their answers. If you don't think this question is resolved by those answers, let me know. Otherwise this might get closed as a duplicate. Commented Jan 21, 2022 at 20:43
  • @jcalz The linked answers seem to explain the core issue—function argument contravariance. My difficulty is specifically in the context of the implementation signature of an overloaded function. The implementation signature needs to be extremely widely typed, allowing for all possibilities in the overload signatures. Could you add an answer containing the information in your two TS playground links above, so that the effects of contravaiance in the implementation signature are addressed? Commented Jan 24, 2022 at 17:15

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.