Home > Mobile >  Shouldn't Typescript pick the most specific function implementation?
Shouldn't Typescript pick the most specific function implementation?

Time:10-14

I have the following code:


type allPossibileTypes = 'my-first-type' | 'my-second-type' | 'my-third-type';
type genericFunction = (innerVariable: any) => void;

class A {
   doSomethingWith(inputType: 'my-first-type', callback: (innerVariable: string) => void);
   doSomethingWith(inputType: allPossibileTypes, callback: genericFunction);
   doSomethingWith(inputType: string, callback: any) {
      // function logic here
   }
}

If I try to call the function like this:

AInstance.doSomething('my-first-type', ...);

I expect that typescript will hint me to the (innerVariable: string) => void for the second parameter, yet instead, it hints me to the genericFunction type. Until now, I thought that when picking type hints, typescript will choose the most specific implementation that it can use, am I mistaken in this?

If yes, how could I achieve to define a function, which allows me to use as the first parameter, only specific strings, and on some concrete occasions, based on the first parameter, give me additional type hints?

CodePudding user response:

You need to exclude 'my-first-type' from allPossibileTypes in your overloads:

type allPossibileTypes = 'my-first-type' | 'my-second-type' | 'my-third-type';
type genericFunction = (innerVariable: any) => void;

class A {
    doSomethingWith(inputType: 'my-first-type', callback: (innerVariable: string) => void): void
    doSomethingWith(inputType: Exclude<allPossibileTypes, 'my-first-type'>, callback: genericFunction): void
    doSomethingWith(inputType: string, callback: any) {
        // function logic here
    }
}

new A().doSomethingWith('my-first-type', (a: string) => void 0); // ok
new A().doSomethingWith('my-first-type', (a: number) => void 0) // error


Playground

Without Exclude both versions with number and string are valid

P.S.

interface test { prop1: string, prop2: string };

type ToBool<T> = {
  [Prop in keyof T]: boolean
}

type Result = ToBool<test>
  • Related