Skip to content

Can't assign result of function of type T to ReturnType<T> #31811

@Jamesernator

Description

@Jamesernator

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions