Description
TypeScript Version: typescript@3.6.0-dev.20190606
Search Terms:
generic ReturnType, ReturnType assign
Explanation
TypeScript seems to treat the return type of a generic not as the ReturnType<T>
but the type it extends from. Basically in this example we get a type error (even though instance
is correctly inferred as Foo
) because IFoo
is not assignable to ReturnType<T>
:
interface IFoo {
someMethod(): string;
}
class Foo implements IFoo {
static create(p: number) {
return new Foo(p)
}
constructor(readonly p: number) { }
someMethod = () => 'a';
}
function createSomeInterfaceInstance<T extends (p: number) => IFoo>(factoryFunction: T): ReturnType<T> {
// This is a TypeError that IFoo is not assignable to ReturnType<T>
return factoryFunction(12)
}
const instance = createSomeInterfaceInstance(Foo.create);
Now this is hackable-around in two different ways, one by explicitly adding a generic for the return type of T
e.g.:
function createSomeInterfaceInstance<K extends IFoo, T extends (p: number) => K>(factoryFunction: T): K
Or just by using a type intersection on the return type e.g.:
function createSomeInterfaceInstance<T extends (p: number) => IFoo & ReturnType<T>>(factoryFunction: T): ReturnType<T>
But both of these solutions feel pretty hacky, it would instead be better if TypeScript inferred the type of factoryFunction(10)
to be IFoo & ReturnType<T>
instead of just IFoo
.
Playground Link: playground-link
Related Issues:
Probably related: #29133