Cette question est l'analogon directe à la vérification de type de classe avec TypeScript
J'ai besoin de savoir à l'exécution si une variable de type any implémente une interface. Voici mon code:
interface A{
member:string;
}
var a:any={member:"foobar"};
if(a instanceof A) alert(a.member);
Si vous entrez ce code dans le terrain de jeu dactylographié, la dernière ligne sera marquée comme une erreur, "Le nom A n'existe pas dans la portée actuelle". Mais ce n'est pas vrai, le nom existe dans la portée actuelle. Je peux même changer la déclaration de variable en var a:A={member:"foobar"};
sans plainte de l'éditeur. Après avoir parcouru le Web et trouvé l'autre question sur SO, j'ai changé l'interface en classe, mais je ne peux plus utiliser les littéraux d'objet pour créer des instances.
Je me demandais comment le type A pouvait disparaître comme ça, mais un coup d'œil au javascript généré explique le problème:
var a = {
member: "foobar"
};
if(a instanceof A) {
alert(a.member);
}
Il n'y a pas de représentation de A en tant qu'interface, donc aucune vérification de type d'exécution n'est possible.
Je comprends que javascript en tant que langage dynamique n'a pas de concept d'interfaces. Existe-t-il un moyen de taper la vérification des interfaces?
La saisie semi-automatique du terrain de jeu tapuscrit révèle que le tapuscrit offre même une méthode implements
. Comment puis-je l'utiliser?
Réponses:
Vous pouvez obtenir ce que vous voulez sans le
instanceof
mot - clé, car vous pouvez maintenant écrire des protecteurs de type personnalisés:Beaucoup de membres
Si vous devez vérifier un grand nombre de membres pour déterminer si un objet correspond à votre type, vous pouvez plutôt ajouter un discriminateur. L'exemple ci-dessous est l'exemple le plus élémentaire et vous oblige à gérer vos propres discriminateurs ... vous devez approfondir les modèles pour vous assurer d'éviter les discriminateurs en double.
la source
isInstanceOfA(instantiatedB)
retourner vrai, mais vous voudriezisInstanceOfB(instantiatedA)
retourner faux. Pour que ce dernier se produise, le discriminateur de B ne devrait-il pas être «I-AM-A»?Dans TypeScript 1.6, la protection de type définie par l'utilisateur fera le travail.
Et tout comme Joe Yang l'a mentionné: depuis TypeScript 2.0, vous pouvez même tirer parti du type d'union balisé.
Et ça marche
switch
aussi.la source
object is type
etobject instanceof class
est que, le type dans TypeScript est structurel, il ne se soucie que de la "forme" au lieu d'où un objet a obtenu la forme: un objet simple ou une instance d'une classe, cela n'a pas d'importance.type
propriété. Dans ce cas, cela fonctionne. Cet exemple ne montre pas ce fait.tapuscrit 2.0 présente l'union étiquetée
Fonctionnalités de Typescript 2.0
la source
Qu'en est-il des protections de type définies par l'utilisateur? https://www.typescriptlang.org/docs/handbook/advanced-types.html
la source
(pet as Fish).swim !== undefined;
cela a fonctionné.C'est maintenant possible, je viens de publier une version améliorée du
TypeScript
compilateur qui offre des capacités de réflexion complètes. Vous pouvez instancier des classes à partir de leurs objets de métadonnées, récupérer des métadonnées à partir de constructeurs de classes et inspecter l'interface / les classes lors de l'exécution. Vous pouvez le vérifier iciExemple d'utilisation:
Dans l'un de vos fichiers dactylographiés, créez une interface et une classe qui l'implémente comme suit:
imprimons maintenant la liste des interfaces implémentées.
compilez avec reflec-ts et lancez-le:
Voir réflexion.d.ts pour les
Interface
détails du méta-type.MISE À JOUR: Vous pouvez trouver un exemple de travail complet ici
la source
implements
maiscomme ci - dessus où des protections définies par l'utilisateur ont été utilisées, mais cette fois avec un prédicat de fonction de flèche
la source
Voici une autre option: le module ts-interface-builder fournit un outil au moment de la construction qui convertit une interface TypeScript en un descripteur d'exécution, et ts-interface-checker peut vérifier si un objet le satisfait.
Pour l'exemple d'OP,
Vous devez d'abord exécuter
ts-interface-builder
ce qui produit un nouveau fichier concis avec un descripteur, par exemplefoo-ti.ts
, que vous pouvez utiliser comme ceci:Vous pouvez créer une fonction de protection de type à une ligne:
la source
Je voudrais souligner que TypeScript ne fournit pas de mécanisme direct pour tester dynamiquement si un objet implémente une interface particulière.
Au lieu de cela, le code TypeScript peut utiliser la technique JavaScript pour vérifier si un ensemble approprié de membres est présent sur l'objet. Par exemple:
la source
for (element in obj) {}
) pour vérifier que les deux objets ont les éléments similaires de types similaires.TypeGuards
la source
Sur la base de la réponse de Fenton , voici mon implémentation d'une fonction pour vérifier si un donné
object
a les clés uninterface
a, à la fois totalement ou partiellement.Selon votre cas d'utilisation, vous devrez peut-être également vérifier les types de chacune des propriétés de l'interface. Le code ci-dessous ne fait pas cela.
Exemple d'utilisation:
la source
la source
Parce que le type est inconnu au moment de l'exécution, j'ai écrit le code comme suit pour comparer l'objet inconnu, non pas contre un type, mais contre un objet de type connu:
Voici le code (interface-agnostique) que j'utilise pour la comparaison approfondie:
Voici un exemple de la façon dont je l'utilise.
Dans cet exemple, je m'attends à ce que le JSON contienne un tableau de tuples, dont le deuxième élément est une instance d'une interface appelée
User
(qui a deux éléments facultatifs).La vérification de type de TypeScript garantira que mon exemple d'objet est correct, puis la fonction assertTypeT vérifie que l'objet inconnu (chargé à partir de JSON) correspond à l'exemple d'objet.
Vous pouvez invoquer une vérification comme celle-ci dans l'implémentation d'un type de garde défini par l'utilisateur.
la source
Vous pouvez valider un type TypeScript lors de l'exécution en utilisant ts-validate-type , comme cela (nécessite un plugin Babel cependant):
la source