2017-06-27 3 views
0

Comment puis-je vérifier (à l'exécution) si un objet inconnu est un certain type? Et puis le convertir formellement à ce type et faire quelque chose avec?Vérifiez si un objet est un type dans Google Closure et le convertir?

Je voudrais faire quelque chose comme ceci:

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

Fruit est une classe avec le nom des attributs et la couleur. Pour être plus précis, je ne peux pas simplement créer un objet Fruit avec un constructeur car je reçois l'objet de JSON.parse.

Jusqu'à présent, j'ai essayé:

if (someObject instanceof Fruit) 

cette résolu à false. Et je l'ai essayé:

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

Mais cela ne semble pas vraiment faire quoi que ce soit .. à-dire, quand je passe someObj qui ne possède pas de propriétés nom ou la couleur, il est toujours traité comme un Fruit. Peut-être que j'ai besoin d'une solution plus complexe/personnalisée? c'est-à-dire, est-ce intégré dans la fermeture ou devrais-je juste vérifier les attributs de mon propre chef?

+1

types de fermeture existent seulement au moment de la compilation. – SLaks

+0

Avec quelques explications supplémentaires sur la façon dont le type de conversion '/ ** @type {Fruit} * /' fonctionne/pourquoi cela ne fonctionne pas ici, j'accepterais "vous ne pouvez pas faire ceci par vous-même" comme réponse . – hubatish

+0

Le test 'instanceof' ne fonctionne que lorsque l'objet est créé avec' new' (ou peut-être lorsque les valeurs JavaScript 'property' sont agencées manuellement). Avez-vous des moyens de tester quel type d'objet provient-il des propriétés? Si tel est le cas, vous pouvez utiliser la conversion de type comme vous le montrez dans votre premier exemple. – owler

Répondre

0

instanceof est ce que vous cherchez. C'est ainsi que vous vérifiez si une valeur donnée a été créée à partir d'une fonction de constructeur spécifique (ou une meilleure classe ES2015).

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

Cependant, dans votre exemple original, qu'est-ce qui fait qu'un objet est un fruit? Vous utilisez des objets anonymes. Un objet ayant une propriété name et color est-il un fruit? C'est un peu flou et très spécifique à la mise en œuvre. Vous devez être capable de vous répondre "Qu'est-ce qui fait un objet un fruit?"

Si vous voulez vérifier si un objet implémente une interface de fruits (a les bonnes propriétés), vous vérifiez simplement pour les propriétés:

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

Le système de fermeture de Closure n'existe qu'au moment de la compilation.

Tout comme en C, les moulages disent simplement au système de type "Je garantis que cette valeur est réellement de ce type, même si vous ne pouvez pas le prouver".
Si ce n'est pas vrai, vous obtenez un comportement indéfini (en particulier avec des optimisations avancées).

+0

Ce n'est pas strictement vrai. La plupart des types sont basés sur des constructeurs ou des interfaces. L'un ou l'autre peut être vérifié lors de l'exécution. –

+0

@ChadKillingsworth: Les interfaces ne peuvent pas être. – SLaks

+0

Bien sûr, ils peuvent - une interface est juste un ensemble de propriétés. Si un objet a des propriétés qui correspondent aux types spécifiques, cela peut être vérifié lors de l'exécution. –