Wykonywanie ćwiczeń to klucz do zrozumienia TypeScripta, przynajmniej dla mnie. Spróbujemy sobie coś ciekawego dzisiaj zrobić.

Przypomnijmy sobie ten kod:

interface FuncWithDescription {
    (...args: any[]): any;
    description: string
  }

  
  const sum123: FuncWithDescription = function(a, b) {
    return a + b
  }
  sum123.description = 'A function that sums two numbers'

  console.log(sum123.description);

Fajna rzecz. Ok, takie coś wymyśliłem:

type FuncHasDesc<T> = T extends {
    (...args: any[]): any;
    description: string
  } ? true: false;

type sum123HasDesc = FuncHasDesc<typeof sum123>;

//type sum123HasDesc = true

Ok, rozbiłem to, aby można było tylko funkcję przekazać:

type FuncHasDesc<T extends {(...args: any[]): any;} > = T extends {description: string} ? true: false;

type sum123HasDesc = FuncHasDesc<typeof sum123>;

//type sum123HasDesc = true

Ok, teraz użyjemy sobie infer:

type FuncDescType<T extends {(...args: any[]): any;} > 
= T extends {description: infer DescType} ? DescType: never;

type Sum123DescType = FuncDescType<typeof sum123>;

// type Sum123DescType = string

Swoją drogą nie musimy używać infera:

type FuncDescType<T extends {(...args: any[]): any;} > 
= T extends {description: any} ? T["description"]: never;

type Sum123DescType = FuncDescType<typeof sum123>;

// type Sum123DescType = string

Natomiast bawiąc się w ten sposób powoli zaczyna nam się w głowie ten TypeScript układać…