How can I check (at runtime) if an unknown object is a certain type? And then formally convert it to that type and do something with it?
I'd like to do something like this:
const /** {Object} */ someObject = {name: 'Apple', color: 'Red'};
if (someObject is Fruit) {
// Convert to {Fruit} and do something with it.
return /** {Fruit} */ (someObject);
}
where Fruit
is a class with the attributes name and color.
To be more specific, I can't just create a Fruit
object with a constructor as I'm getting the object from JSON.parse
.
So far I've tried:
if (someObject instanceof Fruit)
this resolved to false. And I've tried:
const aFruit = /** @type {Fruit} */ someObj;
But this doesn't actually seem to do anything.. ie, when I pass in someObj
that doesn't have properties name or color it is still treated as a Fruit
.
Perhaps I need a more complex/custom solution? ie, is this built into Closure or should I just check the attributes on my own?
instanceof
is what you are looking for. That's how you check if any given value was created from a specific constructor function (or better ES2015 class).
const /** {Object} */ someObject = new Fruit('Apple', 'red');
if (someObject instanceof Fruit) {
// Convert to {Fruit} and do something with it.
return /** {Fruit} */ (someObject);
}
However in your original example, what makes an object a Fruit? You are using anonymous objects. Is any object that has a name
and color
property a fruit? This is a bit unclear and very implementation specific. You need to be able to answer yourself "What makes an object a fruit?"
If you want to check if an object implements a Fruit interface (has the correct properties), you simply check for those properties:
/**
* @param {!Object} obj
* @return {boolean}
*/
function isFruit(obj) {
return obj.color && obj.name;
}