Je teste juste du typographie dans VisualStudio 2012 et j'ai un problème avec son système de type. Mon site html a une balise canvas avec l'identifiant "mycanvas". J'essaye de dessiner un rectangle sur cette toile. Voici le code
var canvas = document.getElementById("mycanvas");
var ctx: CanvasRenderingContext2D = canvas.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);
Malheureusement, VisualStudio se plaint que
la propriété 'getContext' n'existe pas sur la valeur de type 'HTMLElement'
Il marque la deuxième ligne comme une erreur. Je pensais que ce serait simplement un avertissement mais le code ne compile pas. VisualStudio dit que
il y a eu des erreurs de construction. Souhaitez-vous continuer et exécuter la dernière version réussie?
Je n'ai pas du tout aimé cette erreur. Pourquoi n'y a-t-il pas d'appel de méthode dynamique? Après tout, la méthode getContext existe définitivement sur mon élément canvas. Cependant, je pensais que ce problème serait facile à résoudre. Je viens d'ajouter une annotation de type pour le canevas:
var canvas : HTMLCanvasElement = document.getElementById("mycanvas");
var ctx: CanvasRenderingContext2D = canvas.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);
Mais le système de type n'était toujours pas satisfait. Voici le nouveau message d'erreur, cette fois sur la première ligne:
Impossible de convertir «HTMLElement» en «HTMLCanvasElement»: le type «HTMLElement» ne contient pas la propriété «toDataURL» du type «HTMLCanvasElement»
Eh bien, je suis tout à fait pour le typage statique mais cela rend le langage inutilisable. Qu'est-ce que le système de typage veut que je fasse?
METTRE À JOUR:
Typescript n'a en effet aucun support pour l'invocation dynamique et mon problème peut être résolu avec les typecasts. Ma question est essentiellement un double de celui-ci TypeScript: casting HTMLElement
CanvasRenderingContext2D
au lieu deany
type pour le contexte de canevas."2d"
et.getContext("2d")
retournera avec le typeCanvasRenderingContext2D
. Vous n'avez pas besoin de le diffuser explicitement.la source
Alors que d'autres réponses promeuvent les assertions de type (c'est ce qu'elles sont - TypeScript n'a pas de castes de type qui changent réellement le type; elles sont simplement un moyen de supprimer les erreurs de vérification de type), la manière intellectuellement honnête d'aborder votre problème est d'écouter le messages d'erreur.
Dans votre cas, il y a 3 choses qui peuvent mal tourner:
document.getElementById("mycanvas")
peut retournernull
, car aucun nœud de cet identifiant n'est trouvé (il peut avoir été renommé, pas encore injecté dans le document, quelqu'un peut avoir essayé d'exécuter votre fonction dans un environnement sans accès au DOM)document.getElementById("mycanvas")
peut renvoyer une référence à un élément DOM, mais cet élément DOM n'est pas unHTMLCanvasElement
document.getElementById("mycanvas")
a renvoyé un valideHTMLElement
, c'est bien unHTMLCanvasElement
, mais leCanvasRenderingContext2D
n'est pas pris en charge par le navigateur.Au lieu de dire au compilateur de se taire (et éventuellement de vous retrouver dans une situation où un message d'erreur inutile comme
Cannot read property 'getContext' of null
est émis), je vous recommande de prendre le contrôle des limites de votre application.Assurez-vous que l'élément contient un HTMLCanvasElement
Assurez-vous que le contexte de rendu est pris en charge par le navigateur
Usage:
Voir TypeScript Playground .
la source
Il semble que cela soit corrigé dans la version .9 de TypeScript: http://blogs.msdn.com/b/typescript/archive/2013/03/25/working-on-typescript-0-9-generics-overload- on-constants-and-compiler-performance.aspx Voir la section "Surcharge sur les constantes" où la balise canvas est explicitement affichée.
la source
J'ai eu le même problème, mais avec SVGSVGElement au lieu de HTMLCanvasElement. La conversion en SVGSVGElement a donné une erreur de compilation:
Impossible de convertir «HTMLElement» en «SVGSVGElement»: le
type «HTMLElement» ne contient pas la propriété «width» du type «SVGSVGElement».
Il manque la propriété «onmouseleave» du type «HTMLElement» de type «SVGSVGElement».
Si corrigé par le premier casting à 'any':
ou de cette façon (cela a le même effet)
Maintenant mySvg est fortement typé comme SVGSVGElement.
la source
C'est un vieux sujet ... peut-être mort en 2012, mais passionnant et nouveau pour VS Code et dactylographié.
J'ai dû faire ce qui suit pour que cela fonctionne dans VS Code avec les références de package suivantes.
Version dactylographiée:
la source
Vous devrez peut-être ajouter
DOM
àcompilerOptions.lib
votretsconfig.json
.la source