Búsqueda de sitios web

¿Cómo obtengo el tipo de una variable objeto en Typescript/Angular 7?


Estoy tratando de obtener el tipo/clase de una instancia de objeto personalizado. Esto luego se usará como un parámetro de tipo pasado a una función genérica en lugar de usar simplemente el tipo 'any'.

He probado foo.prototype, Object.getPrototypeOf(foo), typeof foo, foo.constructor, foo.constructor.name, etc., pero aún no he encontrado una manera de devolver el tipo/clase del objeto en sí. El ejemplo a continuación da una idea de lo que quiero lograr: no funciona aquí porque constructor.name solo devuelve el nombre del tipo:

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… 
}

Soy bastante nuevo en TypeScript y JavaScript, así que no estoy seguro de que esto siquiera sea posible, pero con suerte hay una manera de hacer esto.

Gracias por cualquier ayuda con esto.

Respuesta #1

En tu ejemplo no deberías añadir el tipo al genérico en absoluto. TypeScript puede inferir el tipo en este contexto, porque T se usa como parámetro.

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

Si realmente quieres agregar el genérico aquí, podrías usar typeof.

buildVehicle<typeof vehicle>(vehicle);

Esto es, en este caso, equivalente a

buildVehicle<Car | Bike>(vehicle);

porque no es posible determinar qué tipo de vehículo tiene realmente en tiempo de compilación. Solo podría determinarse en tiempo de ejecución. Pero dado que los tipos de TypeScript se pierden durante la transpilación (ya que se transpilan a JavaScript), no hay forma de hacer eso con tu código actual.

Sin embargo, podrías cambiar tu código para hacerlo determinable en tiempo de compilación.

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"
}

Aunque, en tu caso, esto probablemente no tendría mucho sentido.

Respuesta #2

Intenta usar unión de tipos: type Vehicle=Bike | Car;