J'ai écrit ce code
interface Foo {
abcdef: number;
}
let x: Foo | string;
if (x instanceof Foo) {
// ...
}
Mais TypeScript m'a donné cette erreur:
'Foo' only refers to a type, but is being used as a value here.
Pourquoi cela arrive-t-il? Je pensais que instanceof
pourrait vérifier si ma valeur a un type donné, mais TypeScript ne semble pas aimer ça.
Le problème est que instanceof
est une construction de JavaScript et que, en JavaScript, instanceof
s'attend à une valeur pour l'opérande de droite. Plus précisément, dans x instanceof Foo
JavaScript effectuera une vérification de l'exécution pour voir si Foo.prototype
existe dans la chaîne de prototypes de x
.
Cependant, dans TypeScript, interface
s n'ont aucune émission. Cela signifie que ni Foo
ni Foo.prototype
n'existent à l'exécution, donc ce code va définitivement échouer.
TypeScript essaie de vous dire que cela pourrait jamais fonctionner. Foo
est juste un type, ce n'est pas une valeur du tout!
instanceof
?"Vous pouvez regarder dans gardes de type et gardes de type définis par l'utilisateur .
interface
à un class
?"Vous pourriez être tenté de passer d'un interface
à un class
, mais vous devez comprendre que dans le système de types structurel de TypeScript (où les éléments sont principalement basé sur la forme), vous pouvez produire tout objet ayant la même forme. en tant que classe donnée:
class C {
a: number = 10;
b: boolean = true;
c: string = "hello";
}
let x = new C()
let y = {
a: 10, b: true, c: "hello",
}
// Works!
x = y;
y = x;
Dans ce cas, vous avez x
et y
qui ont le même type, mais si vous essayez d'utiliser instanceof
sur l'un des deux, vous obtiendrez le résultat inverse sur l'autre. Donc, instanceof
ne sera pas vraiment vous en dire beaucoup sur le type si vous tirez parti des types structurels dans TypeScript.
Daniel Rosenwasser a peut-être raison et dandy mais j'ai envie de faire un amendement à sa réponse. Il est tout à fait possible de vérifier l’instance de x, voir l’extrait de code.
Mais il est également facile d'affecter x = y. Maintenant, x ne serait pas une instance de C car y n'avait que la forme de C.
class C {
a: number = 10;
b: boolean = true;
c: string = "hello";
}
let x = new C()
let y = {
a: 10, b: true, c: "hello",
}
console.log('x is C? ' + (x instanceof C)) // return true
console.log('y is C? ' + (y instanceof C)) // return false