检查对象是否是 Google 闭包中的类型,并转换它?

Check if an object is a Type in Google Closure, and convert it?

如何检查(在运行时)未知对象是否为特定类型?然后正式将其转换为该类型并对其进行处理?

我想做这样的事情:

const /** {Object} */ someObject = {name: 'Apple', color: 'Red'};
if (someObject is Fruit) {
  // Convert to {Fruit} and do something with it.
  return /** {Fruit} */ (someObject);
}

其中 Fruit 是具有属性名称和颜色的 class。

更具体地说,当我从 JSON.parse 获取对象时,我不能只使用构造函数创建一个 Fruit 对象。

到目前为止我已经尝试过:

if (someObject instanceof Fruit)

这被判定为错误。我试过了:

const aFruit = /** @type {Fruit} */ someObj;

但这实际上似乎没有做任何事情.. 即,当我传入没有属性名称或颜色的 someObj 时,它仍然被视为 Fruit

也许我需要更 complex/custom 的解决方案?即,这是 Closure 内置的还是我应该自己检查属性?

Closure 的类型系统仅在编译时存在。

就像在 C 中一样,强制转换只是告诉类型系统 "I guarantee that this value actually is of this type, even though you can't prove it"。
如果这不是真的,你会得到未定义的行为(尤其是高级优化)。

instanceof 就是您要找的。这就是你如何检查任何给定值是否是从特定构造函数(或更好的 ES2015 class)创建的。

const /** {Object} */ someObject = new Fruit('Apple', 'red'); 
if (someObject instanceof Fruit) {
  // Convert to {Fruit} and do something with it.
  return /** {Fruit} */ (someObject);
}

但是在您的原始示例中,是什么使对象成为水果?您正在使用匿名对象。有 namecolor 属性 的物体是水果吗?这有点不清楚并且非常具体的实现。您需要能够自己回答 "What makes an object a fruit?"

如果您想检查一个对象是否实现了 Fruit 接口(具有正确的属性),您只需检查这些属性:

/**
 * @param {!Object} obj
 * @return {boolean}
 */
function isFruit(obj) {
  return obj.color && obj.name;
}