Home > Software engineering >  Comparing Generic Types in TypeScript
Comparing Generic Types in TypeScript

Time:09-09

I'm working on a frontend project in Angular for my company in which we query different objects from an API (like Users, Products, etc).

I am currently trying to generalize our services which handle data transfer between our components and the API as they all do pretty much the same (trying to keep it DRY). To achieve this I need to make different API calls depending on the type of my generic.

It basically boils down to this:

public foo<TMyType>(){
        if (TMyType === TypeA) {
            //do stuff
        } else if (TMyType === TypeB) {
            //do other stuff
        } else {
            throw new Error('Invalid type');
        }
    }

Note that I do not want to pass the actual object, but only decide on what to do depending on the generic type I call the function with. I feel like there should be a very simple way to achieve this, but I cannot figure it out.

Many thanks

CodePudding user response:

You can't do types comparison on runtime, but you can do something like this:

function foo<T extends TypeA | TypeB>(a: T) {
    
}

T extends TypeA | TypeB means that generic type T can only be TypeA or TypeB

to distinguish typeA from typeB you have to find a specific property which can tell them apart

for example:

type TypeA = string
type TypeB = { test: string }

function foo<T extends TypeA | TypeB>(a: T) {
    if(typeof a === "string") {
         //... a is TypeA
    } else if("test" in a) {
         //... a is TypeB
    }
}

CodePudding user response:

You could remove some of boilerplate with class inheritance.

class GenericRestService {
     protected endpoint: string = '/stuff';

     constructor(protected httpClient: HttpClient) {}

     makeACall<T>(param: string): Observable<T> {
          return this.httpClient.get<T>(`${this.endpoint}/${param}`)
               .pipe( 
          // some stuff here
               ); 
     }
}
class SpecificRestService extends GenericRestService {
    endpoint = '/otherThings';
}
  • Related