Skip to content

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

Closed
@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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions