TeMo
TeMo

Reputation: 23

How do I get the type from an object variable in Typescript / Angular 7?

I'm trying to get the type/class from an custom object instance. This will then be used as a type parameter passed to a generic function rather than just use the 'any' type.

I've tried foo.prototype, Object.getPrototypeOf(foo), typeof foo, foo.constructor, foo.constructor.name etc but haven't yet found a way to return the objects's type/class itself. The example below gives an idea of what I want to achieve - it doesn't work here because constructor.name only returns the name of the type:

var vehicle 

if (selected == 'car') { 
vehicle = new Car() 
} else { 
vehicle = new Bike()  
} 

var vehicleType = vehicle.constructor.name

buildVehicle<vehicleType>(vehicle) 

buildVehicle<T>(vehicle:T) { 
    do stuff… 
}

I'm pretty new to typescript and javascript so I'm not sure this is even possible, but hopefully there is a way to do this.

Thanks for any help on this.

Upvotes: 2

Views: 2863

Answers (2)

pascalpuetz
pascalpuetz

Reputation: 5428

In your example you shouldn't add the type to the generic at all. TypeScript can infer the type in this context, because T is used a parameter.

// Use it like this: 
buildVehicle(vehicle);

If you really want to add the generic here, you could use typeof.

buildVehicle<typeof vehicle>(vehicle);

This is, in this case, equivalent to

buildVehicle<Car | Bike>(vehicle);

because it is not possible to determine which type vehicle actually has at compile time. It could only be determined at runtime. But since TypeScript types are lost during transpilation (as it transpiles to JavaScript), there is no way to do that with your current code.

You could, however, change your code to make it determinable at compile time.

if (vehicle instanceof Car) {
   buildVehicle<Car>(vehicle); // Vehicle is narrowed down to type "Car"
} else if (vehicle instanceof Bike) { // else would suffice if only 2 possible types
   buildVehicle<Bike>(vehicle); // Vehicle is narrowed down to type "Bike"
}

Though, in your case, this would probably not make much sense.

Upvotes: 1

stesel
stesel

Reputation: 37

Try to use type union: type Vehicle = Bike | Car;

Upvotes: 0

Related Questions