Home > OS >  Typescript arrow functions overloads error 2322
Typescript arrow functions overloads error 2322

Time:12-04

This code below is working fine, but it gives an error for the resolve constant.

const resolve: Resolve
Type '(param: "case 1" | "case 2" | "case 3") => boolean | "string" | 1000' is not assignable to type 'Resolve'.(2322)
// Overloads
type Resolve = {
    (): false;
    (param: 'case 1'): string;
    (param: 'case 2'): number;
    (param: 'case 3'): true;
};

const resolve: Resolve = (param) => {
    switch (param) {
        case 'case 1':
            return 'string';
        case 'case 2':
            return 1000;
        case 'case 3':
            return true;
        default:
            return false;
    }
};

const result = {
    first: resolve('case 1'),
    second: resolve('case 2'),
    third: resolve('case 3'),
    none: resolve()
};

Any idea how to resolve it ?

CodePudding user response:

It's often the case that an overloaded function's implementation signature isn't fully compatible with the overload signatures. When you're using overload syntax, TypeScript uses relaxed rules for compatibility.

In your case, since you're not using overload syntax, you'll have to use a type assertion (after making sure that the function behaves correctly for the overloads):

const resolve = ((param?: "case 1" | "case 2" | "case 3"): string | number | true | false => {
    switch (param) {
        case "case 1":
            return "string";
        case "case 2":
            return 1000;
        case "case 3":
            return true;
        default:
            return false;
    }
}) as Resolve;

(I've also added a type annotation to param and a return type annotation, just for good measure, though it's not uncommon to be really loose in the implementation signature.)

Playground example


Just FWIW, using function overload syntax instead (playground link):

function resolve(param: "case 1"): string;
function resolve(param: "case 2"): number;
function resolve(param: "case 3"): true;
function resolve(): false;
function resolve(param?: "case 1" | "case 2" | "case 3"): string | number | true | false {
    switch (param) {
        case "case 1":
            return "string";
        case "case 2":
            return 1000;
        case "case 3":
            return true;
        default:
            return false;
    }
};

type Resolve = typeof resolve;

...but that's not always possible, it's not uncommon to have to define the type without ever actually implementing it (for instance, in a callback type for an API).

  • Related