6

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?

3
  • 3
    A generic method can not return a non-generic field. You either have to make Something extend the generic object or change the return type to the object. Commented Jul 19, 2017 at 14:26
  • 1
    you have getData and getDataList. Is that a typo? Can you just do this perhaps? protected abstract getData<T[]>(): T[]; protected getData<Something[]>(): Something[] { return this.databaseService().getSomethingList(); } Commented Jul 19, 2017 at 21:18
  • @JGFMK sry, didn't think of it when I was making the example. Commented Jul 20, 2017 at 7:00

3 Answers 3

9

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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();
}

Comments

0

Also you can define Something[] using some thing like this out of your class:

interface Something{
    foo: foo,
    var: var
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.