0

How can I overload a generic method with concrete type? It seems to work if I specify R at class level ie Foo but not at method's level.

class Foo {
    find<R>(arg: R[]): R[] {
        return arg;
    }
}

class Bar extends Foo {
    find(arg: string[]) {
        return super.find(arg);
    }
}

Gives the following error

Property 'find' in type 'Bar' is not assignable to the same property in base type 'Foo'. Type '(arg: string[]) => string[]' is not assignable to type '(arg: R[]) => R[]'. Types of parameters 'arg' and 'arg' are incompatible. Type 'R[]' is not assignable to type 'string[]'. Type 'R' is not assignable to type 'string'.(2416)

1 Answer 1

2

The compiler does not allow it because it would create a hole in the type system. Consider the following:

function findNumbers(obj: Foo) {
    return obj.find([1, 2, 3]);
}

findNumbers(new Bar());

findNumbers should accept an instance of Bar (since Bar extends Foo) but Bar.prototype.find can only accept string[] whereas Foo.prototype.find accepts any array. In TypeScript's type system an instance of a subclass should be able to do everything an instance of a superclass can. In your example Bar.prototype.find wouldn't be able to accept a number[] whereas Foo.prototype.find could. Therefore your Bar would not be a valid subclass of Foo.

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

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.