1

I'm trying to assign a generic type to another as default and return the assignee generic type in a function on an abstract class. I wanted it to be totally straightforward for the extended class for override it using the default value with no success.

This is a part (reduced) of my abstract class:

export abstract class ServicioRest <T> {

    public listarPorId<K = T>(entidad?: T): Promise<K> {
        return new Promise<K>((resolve: Function, reject: (error: any) => void): void => {
            //some code
        });
    }

}

And these are some ways I've tried to create my extended class. Just the last two (4 and 5) worked out:

1)

class EntityService extends ServicioRest<IEntity> {

        public listarPorId(entidad?: IEntity): Promise<IEntity> {
            return super.listarPorId(entidad);
        }

    }

2)

class EntityService extends ServicioRest<IEntity> {

        public listarPorId<IEntity>(entidad?: IEntity): Promise<IEntity> {
            return super.listarPorId(entidad);
        }

    }

3)

class EntityService extends ServicioRest<IEntity> {

        public listarPorId(entidad?: IEntity) {
            return super.listarPorId(entidad);
        }

    }

4)

class EntityService extends ServicioRest<IEntity> {

        public listarPorId<K=IEntity>(entidad?: IEntity): Promise<K> {
            return super.listarPorId(entidad);
        }

    }

5)

class EntityService extends ServicioRest<IEntity> {

        public listarPorId<K>(entidad?: IEntity): Promise<K> {
            return super.listarPorId(entidad);
        }

    }

The ones that don't work make the compiler alert on this error:

ERROR in src/app/modules/rest/models/servicio-rest.spec.ts(31,16): error TS2416: Property 'listarPorId' in type 'EntityService' is not assignable to the same property in base type 'ServicioRest'. Type '(entidad?: IEntity...' is not assignable to type '<K = IEntity>(entidad: IEntity...'. Type 'Promise<IEntity>' is not assignable to type 'Promise<K>'. Type 'IEntity' is not assignable to type 'K'.

Although the last two work out, I don't like them because I can't restrict K to be IEntity. Is there any way to achive that restriction?

Nick2324
  • 45
  • 1
  • 6
  • Why isn't the abstract superclass method defined like `public listarPorId(entidad?: T): Promise`? What purpose does `K` serve? If you have a value `s` of type `ServicioRest`, do you ever want to call `s.listarPorId(123)`? – jcalz Aug 23 '19 at 16:29
  • @jcalz Yes, I do. In fact, there are some cases where I have to call my rest services sending one entity and retrieving a different one. It usually happens when I have to run a service that executes complex processes in the server side and it returns a response with a code to track my request and any other information messages. It also happens when requesting third party APIs – Nick2324 Aug 25 '19 at 12:38
  • But do you want a single `s` to do both `s.listarPorId(123)` and `s.listarPorId(123)`? Or would you be okay if each `s` only had a single input-output type pair. That is, what about `ServicioRest.listarPorId(t: T): Promise` instead of `ServicioRest.listarPorId(t: T): Promise`? – jcalz Aug 25 '19 at 14:17
  • @jcalz At the end I've decided to leave my class without the second Type parameter (K). That was because I realized I was giving my class to much load and I wanted it to solve all of my problems with http API and it's not going to pay off as much as I thought. Even so, my doubt will persist in that, to me, angular should be able to manage those defaults without making me explicitly set that second parameter (K) if that's is my intention (possibly if I marked my class as somewhat like "final" in java). – Nick2324 Sep 02 '19 at 15:01

0 Answers0