Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic method in Typescript

I have an abstract class which has an abstract generic method, which looks something like this

protected abstract getData<T>(): T[];

Then I have a class which extends this abstract class. Since getData is abstract I have to make implementation of it in the child class.

And it looks something like this

protected getDataList<T>(): T[] {
    return this.databaseService().getSomethingList();
}

getSomethingList()returns Something[]

I get following error though

Type 'Something[]' is not assignable to type 'T[]'.

I tried few things to resolve this error, but seem to have to make the child implementation generic as well for Typescript to be happy. The above implementation was fine until I upgrade Typescript from 2.2.1 to 2.4.1.

So I'm wondering how I can make my code compliant again with Typescript 2.4.1?

like image 909
starcorn Avatar asked Jul 19 '17 14:07

starcorn


2 Answers

I believe you are trying to set it up so that the entire abstract base is parametrized by a particular type that the derived instance must reify. Here is how you would do that:

abstract class Foo<T> {
    protected abstract getData(): T[];
}

class Something { }
class SomethingFoo extends Foo<Something> {
    protected getData(): Something[] {
        // implement here
    }
}

Note that the function itself isn't parametrized, since the caller of the function isn't the one who gets to decide what type this function will return. Instead, the containing type is parametrized, and any derivations of it specify the corresponding type argument.

like image 79
Asad Saeeduddin Avatar answered Nov 15 '22 08:11

Asad Saeeduddin


Your implementation:

protected getDataList<T>(): T[] {
    return this.databaseService().getSomethingList();
}

Is wrong in that T is not substituted in any way. This is called a useless generic https://basarat.gitbooks.io/typescript/docs/types/generics.html

Fix

protected getDataList(): Something[] {
    return this.databaseService().getSomethingList();
}
like image 24
basarat Avatar answered Nov 15 '22 08:11

basarat