Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding a generic method in typescript

Tags:

typescript

I am trying to create one base class AbstractQuery and inherit it by child classes and then override some of its methods.

class AbstractQuery {
    public before<A, S>(context: Context<A>, args: A, source?: S): Promise<A> {
        return Promise.resolve(args);
    }
}

Now I would like to override above AbstractQuery::before method in my child class:

class FindBookByIdQuery extends AbstractQuery {
    public before(context: Context<arguments.ID>, args: arguments.ID): Promise<arguments.ID> {
        this.log.debug('hook before args', args);
        return Promise.resolve(args);
    }
}

But I am getting error:

[ts] Property 'before' in type 'FindBookByIdQuery' is not assignable to the same property in base type 'AbstractQuery'. Type '(context: Context, args: ID) => Promise' is not assignable to type '(context: Context, args: A, source?: S) => Promise'. Types of parameters 'context' and 'context' are incompatible. Type 'Context' is not assignable to type 'Context'. Type 'A' is not assignable to type 'ID'. [2416]

like image 683
Vishnu Singh Avatar asked Sep 17 '25 04:09

Vishnu Singh


1 Answers

TypeScript is right to point out the mistake. In AbstractQuery, the context used by the before method is bound with its type parameter. However, in FindBookByIdQuery not such relation exists.

If you want to allow before to have variadic behavior, overload its definition. Consider this example:

declare abstract class Foo<T> {
    before<U>(context: U): Promise<U>;
    before(context: T): Promise<T>
}

declare class Bar<T> extends Foo<T> {
    before(context: T): Promise<T>
}

Here, before can be generic (first overload) or depend on some other type. In this example. this other type is the type parameter of the class itself.

like image 161
Karol Majewski Avatar answered Sep 19 '25 21:09

Karol Majewski