Overload signature is not compatible with its implementation signature

Viewed 1514

I got stuck at overload function at typescript, I did look the doc everything makes sense, even tried myself... but when I implement my own function, it screwed up.

async function triggerValidation<Name extends keyof Data>(payload: {
    name: Extract<keyof Data, string>;
    value?: Data[Name];
    forceValidation?: boolean;
  }[]): Promise<boolean>;
async function triggerValidation<Name extends keyof Data>(payload: {
    name: Extract<keyof Data, string>;
    value?: Data[Name];
    forceValidation?: boolean;
  }): Promise<boolean> {
}

enter image description here

So I want to accept an object or array for my function, but it giving me type error.

1 Answers

Short Answer

so I want to accept an object or array for my function...

You can accept an array or an object without using overloads. Instead, you can use a union type with a user-defined type guard like this (playground link):

type Data = {};

type Payload<Name extends keyof Data> = {
    name: Extract<keyof Data, string>;
    value?: Data[Name];
    forceValidation?: boolean;
}

const isArray = <T>(input: any | any[]): input is T[] =>
    input.constructor === Array;

async function triggerValidation<Name extends keyof Data>(
    payload: Payload<Name> | Payload<Name>[]
): Promise<boolean> {

    if (isArray(payload)) {
        console.log(payload.length);
    } else {
        console.log(payload.forceValidation);
    }

    return false;
}

About Function Overloads

Using a function overload would provide an additional benefit if you were wanting to support only certain parameter list combinations like this:

function myFunc(p1: string, p2: boolean): void;
function myFunc(p1: number, p2: Date): void;
function myFunc(p1: string | number, p2: boolean | Date): void {
    if (typeof p1 === 'string') {
        console.log(p1, p2);
    } else {
        console.log(p1, p2);
    }
}

Now there is an error when the parameters do not line up with the supported overload signatures.

myFunc('foo', false); // works
myFunc(10, new Date()); // works
myFunc('foo', new Date()); // error
myFunc(10, false); // error

Although it will not provide any additional value (because you only have one parameter in your function), here for completeness sake is how your original solution would work with a function overload.

function triggerValidation<Name extends keyof Data>(payload: Payload<Name>): Promise<boolean>
function triggerValidation<Name extends keyof Data>(payload: Payload<Name>[]): Promise<boolean>
async function triggerValidation<Name extends keyof Data>(
    payload: Payload<Name> | Payload<Name>[]
): Promise<boolean> {
    if (isArray(payload)) {
        console.log(payload.length);
    } else {
        console.log(payload.forceValidation);
    }
    return false;
}

Here the overload part works but does not provide any additional value, because there are no correlated parameter lists to support.

Related