TypeScript: Type of function with automatic return type by extends generic

Solution for TypeScript: Type of function with automatic return type by extends generic
is Given Below:

I try to make typed function whitch returns child type over parent;
We have…

class X { }

class A extends X {
  hi() { ... }
}

class B extends X {
  hello() { ... }
}

type Foo<T extends X = X> = () => T;

Then, i write various functions

const fa: Foo = () => {
  return new A();
}

const fb: Foo = () => {
  return new B();
}

Then, I store result in variables

const a = fa();
const b = fb();

But, if I try to call owned methods of classes A and B, i won`t. Because all types are X

a.hi() // error
b.hello() // error

How correct this mistake if you can not set generic manually, like a = fa<A>() ?

Thanks!

Lets start from class X. This class does not have any methods.

You expect Foo to accept one generic parameter with default value X.

Since you have defined fa and fb functions with type Foo without explicit generic parameter, default value has been applied.

In fact, each function has type of Foo<X>. Since X does not have any methods, you are not allowed to call them.

If you want to make a function which returns any class inherited from X,
consider this example:

class X {
    tag: 'X' = 'X'
}

class A extends X {
    hi() { }
}

class B extends X {
    hello() { }
}

class C {}

const fa = () => {
    return new A();
}

const fb = () => {
    return new B();
}

const x = <T extends typeof X>(arg: T) => new arg();

const a = x(A) // ok
const b = x(B) // ok;
const c = x(C) // error

Playground

Please keep in mind, that TS has structural type system, this means that class X{} and class C{} are equal from type point of view. To make sure TS is able to distinguish them you need to add some property to X. I added tag