Search code examples
typescriptes6-promise

Typescript - Returning a promise from a generic method


I have an issue where I am trying to return a promise from one of my methods, however, it complains that the type 'is not assignable'. See example below:

interface Test {
    prop1: string
}

interface Interface {
    oneMethod<T>(): Promise<T>;
}

class implementation implements Interface {
    oneMethod<Test>(): Promise<Test> {
        return Promise.resolve({
            prop1: 'test'
        });
    }
}

I get the error:

error TS2322: Type 'Promise<{ prop1: string; }>' is not assignable to type 'Promise<Test>'.
  Type '{ prop1: string; }' is not assignable to type 'Test'.

I have tried adding 'as Test' to the return object but that then returns the issue 'cannot be converted to Type Test'

Annoyingly, this works fine:

class anotherImp {

    oneMethod(): Promise<Test> {
        return Promise.resolve({
            prop1: 'test'
        });
    }
}

but this is not implementing my generic interface. If I remove the T from the oneMethod signature in the interface, then I get an error about the Promise not knowing T (Cannot find name 'T'). Removing from both gives me the error that Promise must implement a type (Generic type 'Promise' requires 1 type argument(s).)

Any thoughts much appreciated.

Thanks Iain


Solution

  • Try it this way:

    interface Test {
        prop1: string
    }
    
    interface Interface<T> {
        oneMethod(): Promise<T>;
    }
    
    class implementation implements Interface<Test> {
        oneMethod(): Promise<Test> {
            return Promise.resolve({
                prop1: 'test'
            });
        }
    }
    

    When you define a method/function as method<Type>(): Type you're not returning the existent type Type (if any). You're telling TypeScript that that method is generic and will return whatever type you indicate through the type parameter.

    Normally, you won't have a generic method in a non-generic interface. It is better to define the interface as generic, so the method depends on the type of the interface. Otherwise, you could just define a type as generic function forget about the interface.