Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the type of T inside generic method in Typescript?

I have a generic method in a class.,

export class BaseService {
    public getAll<T>(): Observable<T> {
        // get type of T

        // const type = typeof(T); // Tried this but getting compilation exceptions 

        return this.http.get<T>(this.actionUrl + 'getAll');
    }
}

I'll be calling the method like below, from few other typescript classes.

this.service.getAll<SubscriberData>().subscribe(response => {
      // Response
    }, error => {
      console.log(error);
    }, () => {
      // do something commonly
    });

When i tried this getting the following exception

const type = typeof(T); 

'T' only refers to a type, but is being used as a value here.

Edit:

I'm trying to get the type of a class which is calling the generic method. For Ex: getAll<SubscriberData> i want to get the type SubscriberData inside that method.

How can i do this?

like image 337
RajeshKdev Avatar asked May 27 '18 08:05

RajeshKdev


People also ask

What is T in TypeScript type?

This article opts to use the term type variables, coinciding with the official Typescript documentation. T stands for Type, and is commonly used as the first type variable name when defining generics. But in reality T can be replaced with any valid name.

How do you pass a generic type in TypeScript?

Assigning Generic ParametersBy passing in the type with the <number> code, you are explicitly letting TypeScript know that you want the generic type parameter T of the identity function to be of type number . This will enforce the number type as the argument and the return value.

What is generic data type in TypeScript?

Generics allow creating 'type variables' which can be used to create classes, functions & type aliases that don't need to explicitly define the types that they use. Generics makes it easier to write reusable code.


1 Answers

You can access the constructor reference of a class in a class decorator, a property in a property (or accessor) decorator, or a parameter in a parameter decorator (using reflect-metadata).

Unfortunately, generic type arguments are not available at runtime this way, they'll always yield the runtime equivalent of a simple Object type.

Instead, you can supply the constructor reference, which you can also use to infer the generic type (i.e. instead of specifying the generic type, you specify the corresponding constructor reference of that generic type):

export class BaseService {
    public getAll<T>(TCtor: new (...args: any[]) => T): Observable<T> {
        // get type of T
        const type = typeof(TCtor);

        // ...
    }
}

And then use it like this:

new BaseService().getAll(DataClass); // instead of 'getAll<DataClass>()'

Demo on playground

The type new (...args: any[]) => T simply says: a newable type (i.e. a class/constructor) that returns the generic T type (in other words, the corresponding class/constructor for the generic T instance type).

like image 95
John Weisz Avatar answered Oct 11 '22 00:10

John Weisz