Ich teste nur Typoskript in VisualStudio 2012 und habe ein Problem mit dem Typsystem. Meine HTML-Site hat ein Canvas-Tag mit der ID "mycanvas". Ich versuche ein Rechteck auf diese Leinwand zu zeichnen. Hier ist der Code
var canvas = document.getElementById("mycanvas");
var ctx: CanvasRenderingContext2D = canvas.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);
Leider beschwert sich VisualStudio darüber
Die Eigenschaft 'getContext' ist für den Wert vom Typ 'HTMLElement' nicht vorhanden.
Es markiert die zweite Zeile als Fehler. Ich dachte, dies wäre nur eine Warnung, aber der Code wird nicht kompiliert. VisualStudio sagt das
Es gab Build-Fehler. Möchten Sie fortfahren und den letzten erfolgreichen Build ausführen?
Dieser Fehler hat mir überhaupt nicht gefallen. Warum gibt es keinen dynamischen Methodenaufruf? Immerhin existiert die Methode getContext definitiv auf meinem Canvas-Element. Ich dachte jedoch, dieses Problem wäre leicht zu lösen. Ich habe gerade eine Typanmerkung für Canvas hinzugefügt:
var canvas : HTMLCanvasElement = document.getElementById("mycanvas");
var ctx: CanvasRenderingContext2D = canvas.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);
Aber das Typensystem war immer noch nicht zufrieden. Hier ist die neue Fehlermeldung, diesmal in der ersten Zeile:
'HTMLElement' kann nicht in 'HTMLCanvasElement' konvertiert werden: Typ 'HTMLElement' fehlt die Eigenschaft 'toDataURL' vom Typ 'HTMLCanvasElement'
Nun, ich bin ganz auf statisches Tippen aus, aber das macht die Sprache unbrauchbar. Was möchte das Typsystem von mir?
AKTUALISIEREN:
Typescript unterstützt in der Tat keinen dynamischen Aufruf und mein Problem kann mit Typecasts gelöst werden. Meine Frage ist im Grunde ein Duplikat dieses einen TypeScript: Casting HTMLElement
CanvasRenderingContext2D
anstelle vonany
Typ für den Canvas-Kontext zu verwenden."2d"
und.getContext("2d")
gibt es mit dem Typ zurückCanvasRenderingContext2D
. Sie müssen es nicht explizit umsetzen.quelle
Während andere Antworten Typensicherungen fördern (das ist es, was sie sind - TypeScript hat keine Typumwandlungen , die den Typ tatsächlich ändern; sie sind lediglich eine Möglichkeit, Fehler bei der Typprüfung zu unterdrücken), besteht die intellektuell ehrliche Art, sich Ihrem Problem zu nähern, darin, sich das anzuhören Fehlermeldungen.
In Ihrem Fall können drei Dinge schief gehen:
document.getElementById("mycanvas")
Möglicherweise wird zurückgegebennull
, weil kein Knoten dieser ID gefunden wurde (er wurde möglicherweise umbenannt und noch nicht in das Dokument eingefügt. Möglicherweise hat jemand versucht, Ihre Funktion in einer Umgebung ohne Zugriff auf DOM auszuführen.)document.getElementById("mycanvas")
Möglicherweise wird ein Verweis auf ein DOM-Element zurückgegeben, aber dieses DOM-Element ist keinHTMLCanvasElement
document.getElementById("mycanvas")
hat eine gültige zurückgegebenHTMLElement
, es ist zwar eineHTMLCanvasElement
, aber dieCanvasRenderingContext2D
wird vom Browser nicht unterstützt.Anstatt dem Compiler zu sagen, er solle den Mund halten (und sich möglicherweise in einer Situation befinden, in der eine nutzlose Fehlermeldung wie
Cannot read property 'getContext' of null
angezeigt wird), empfehle ich, die Kontrolle über Ihre Anwendungsgrenzen zu übernehmen.Stellen Sie sicher, dass das Element ein HTMLCanvasElement enthält
Stellen Sie sicher, dass der Renderkontext vom Browser unterstützt wird
Verwendung:
Siehe TypeScript-Spielplatz .
quelle
Es scheint, dass dies in der .9-Version von TypeScript korrigiert wird: http://blogs.msdn.com/b/typescript/archive/2013/03/25/working-on-typescript-0-9-generics-overload- on-constants-and-compiler-performance.aspx Siehe Abschnitt "Überladen von Konstanten", in dem das Canvas-Tag explizit angezeigt wird.
quelle
Ich hatte das gleiche Problem, aber mit SVGSVGElement anstelle von HTMLCanvasElement. Das Casting in SVGSVGElement ergab einen Fehler bei der Kompilierung:
'HTMLElement' kann nicht in 'SVGSVGElement' konvertiert werden:
Typ 'HTMLElement' fehlt die Eigenschaft 'width' vom Typ 'SVGSVGElement'.
Typ 'SVGSVGElement' fehlt die Eigenschaft 'onmouseleave' vom Typ 'HTMLElement'.
Wenn es durch erstes Casting auf "any" behoben wurde:
oder auf diese Weise (es hat den gleichen Effekt)
Jetzt ist mySvg stark als SVGSVGElement typisiert.
quelle
Dies ist ein altes Thema ... vielleicht bis 2012 tot, aber aufregend und neu für VS Code und Typoskript.
Ich musste Folgendes tun, damit dies in VS Code mit den folgenden Paketreferenzen funktioniert.
Typoskript-Version:
quelle
Sie können hinzufügen müssen ,
DOM
umcompilerOptions.lib
in Ihremtsconfig.json
.quelle