टाइपस्क्रिप्ट: टाइप सिस्टम के साथ समस्याएं


101

मैं VisualStudio 2012 में टाइपस्क्रिप्ट का परीक्षण कर रहा हूं और इसके प्रकार प्रणाली के साथ एक समस्या है। मेरे html साइट में आईडी "mycanvas" के साथ एक कैनवास टैग है। मैं इस कैनवास पर एक आयत बनाने की कोशिश कर रहा हूँ। यहाँ कोड है

var canvas = document.getElementById("mycanvas");
var ctx: CanvasRenderingContext2D = canvas.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);

दुर्भाग्य से VisualStudio की शिकायत है

संपत्ति 'getContext' का प्रकार 'HTMLElement' के मूल्य पर मौजूद नहीं है

यह त्रुटि के रूप में दूसरी पंक्ति को चिह्नित करता है। मैंने सोचा था कि यह केवल एक चेतावनी होगी लेकिन कोड संकलित नहीं करता है। VisualStudio का कहना है कि

बिल्ड एरर थे। क्या आप अंतिम सफल निर्माण जारी रखना और चलाना चाहेंगे?

मुझे यह त्रुटि बिल्कुल पसंद नहीं आई। कोई डायनेमिक विधि आमंत्रण क्यों नहीं है? सभी विधि के बाद getContext निश्चित रूप से मेरे कैनवास तत्व पर मौजूद है। हालाँकि मुझे लगा कि इस समस्या को हल करना आसान होगा। मैंने अभी कैनवास के लिए एक प्रकार का एनोटेशन जोड़ा है:

var canvas : HTMLCanvasElement = document.getElementById("mycanvas");
var ctx: CanvasRenderingContext2D = canvas.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);

लेकिन टाइप सिस्टम अभी भी संतुष्ट नहीं था। यहाँ नई त्रुटि संदेश है, इस बार पहली पंक्ति में:

'HTMLElement' को 'HTMLCanvasElement' में नहीं बदल सकते: 'HTMLCanvasElement' प्रकार से 'HTMLElement' टाइप की गई संपत्ति 'toDataURL' गायब है।

ठीक है, मैं स्टैटिक टाइपिंग के लिए बाहर हूं, लेकिन इससे भाषा बेकार हो जाती है। टाइप सिस्टम मुझे क्या करना चाहता है?

अपडेट करें:

टाइपस्क्रिप्ट में वास्तव में गतिशील आह्वान का कोई समर्थन नहीं है और मेरी समस्या टाइपकास्ट के साथ हल की जा सकती है। मेरा प्रश्न मूल रूप से इस एक टाइपस्क्रिप्ट का डुप्लिकेट है : कास्टिंग HTMLElement

जवाबों:


223
var canvas = <HTMLCanvasElement> document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");

या anyप्रकार के साथ डायनेमिक लुकअप का उपयोग करना (कोई टाइपकास्टिंग नहीं):

var canvas : any = document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");

आप lib.d.ts में विभिन्न प्रकारों को देख सकते हैं


9
यह ध्यान देने योग्य है कि कैनवास संदर्भ के लिए टाइप के CanvasRenderingContext2Dबजाय इसका उपयोग करना बेहतर है any
इवान कोचूरिन

3
टाइपस्क्रिप्ट 1.8 के बाद से, यह निरंतर स्ट्रिंग तर्क को पहचान लेगा "2d", और .getContext("2d")प्रकार के साथ वापस आ जाएगा CanvasRenderingContext2D। आपको इसे स्पष्ट रूप से डालने की आवश्यकता नहीं है।
मार्कस जार्डेरॉट

13
const canvas =  document.getElementById('stage') as HTMLCanvasElement;

7
कृपया बताएं कि यह कोड सिर्फ एक कोड उत्तर के बजाय ओपी की समस्या को हल करने में मदद क्यों करता है। आपका कोड अलग तरह से क्या करता है, यह कैसे मदद करता है?

आप कॉपी / पेस्ट करते हैं और यह काम करता है। यहाँ क्या समझा जाए? यदि यह आपके लिए काम नहीं करता है, तो आपको अपनी समस्या को समझाना चाहिए और विशेष रूप से पूछना चाहिए।
लीनोह

6

हालांकि अन्य उत्तर टाइप एश्योरेंस को बढ़ावा देते हैं (कि वे क्या हैं - टाइपस्क्रिप्ट में टाइप कास्ट्स नहीं हैं जो वास्तव में टाइप को बदलते हैं; वे केवल टाइपिंग की त्रुटियों को दबाने का एक तरीका है), आपकी समस्या का दृष्टिकोण करने के लिए बौद्धिक रूप से ईमानदार तरीका है सुनने का तरीका। त्रुटि संदेश।

आपके मामले में, 3 चीजें हैं जो गलत हो सकती हैं:

  • document.getElementById("mycanvas")वापस आ सकता है null, क्योंकि उस आईडी का कोई भी नोड नहीं मिला है (इसका नाम बदल दिया गया है, दस्तावेज़ में अभी तक इंजेक्ट नहीं किया जा सकता है, हो सकता है कि किसी ने डोम तक पहुंच के बिना आपके फ़ंक्शन को वातावरण में चलाने की कोशिश की हो)
  • document.getElementById("mycanvas") एक DOM एलिमेंट का संदर्भ लौटा सकता है, लेकिन यह DOM एलिमेंट कोई नहीं है HTMLCanvasElement
  • document.getElementById("mycanvas")एक वैध लौटा HTMLElement, यह वास्तव में एक है HTMLCanvasElement, लेकिन CanvasRenderingContext2Dब्राउज़र द्वारा समर्थित नहीं है।

संकलक को बंद करने के लिए कहने के बजाय (और संभवतः खुद को ऐसी स्थिति में ढूंढना जहां एक बेकार त्रुटि संदेश Cannot read property 'getContext' of nullफेंक दिया जाता है), मैं आपके आवेदन की सीमाओं पर नियंत्रण रखने की सलाह देता हूं।

सुनिश्चित करें कि तत्व में HTMLCanvasElement शामिल है

const getCanvasElementById = (id: string): HTMLCanvasElement => {
    const canvas = document.getElementById(id);

    if (!(canvas instanceof HTMLCanvasElement)) {
        throw new Error(`The element of id "${id}" is not a HTMLCanvasElement. Make sure a <canvas id="${id}""> element is present in the document.`);
    }

    return canvas;
}

सुनिश्चित करें कि रेंडरिंग संदर्भ ब्राउज़र द्वारा समर्थित है

const getCanvasRenderingContext2D = (canvas: HTMLCanvasElement): CanvasRenderingContext2D => {
    const context = canvas.getContext('2d');

    if (context === null) {
        throw new Error('This browser does not support 2-dimensional canvas rendering contexts.');
    }

    return context;
}

उपयोग:

const ctx: CanvasRenderingContext2D = getCanvasRenderingContext2D(getCanvasElementById('mycanvas'))

ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);

टाइपस्क्रिप्ट खेल का मैदान देखें ।


2

ऐसा लगता है कि यह टाइपस्क्रिप्ट के .9 संस्करण में सही किया जा रहा है: http://blogs.msdn.com/b/typescript/archive/2013/03/25/working-on-typescript-0-9-generics-overload- on-constants-and-compiler-performance.aspx "ओवरलोड ऑन कॉन्स्टेंट्स" पर अनुभाग देखें जहां कैनवास टैग स्पष्ट रूप से दिखाया गया है।


1

मुझे वही समस्या थी, लेकिन HTMLCanvasElement के बजाय SVGSVGElement के साथ। SVGSVGElement में कास्टिंग को एक संकलन-समय त्रुटि दी गई:

var mySvg = <SVGSVGElement>document.getElementById('mySvg');

'HTMLElement' को 'SVGSVGElement' में नहीं बदल सकते:
टाइप 'HTMLElement' 'SVGSVGElement' से संपत्ति 'चौड़ाई' गायब है।
टाइप 'SVGSVGElement' टाइप 'HTMLElement' से 'onmouseleave' संपत्ति गायब है।

यदि इसे पहली कास्टिंग के लिए 'किसी भी' से तय किया जाता है:

var mySvg = <SVGSVGElement><any>document.getElementById('mySvg');

या इस तरह (इसका समान प्रभाव है)

var mySvg: SVGSVGElement = <any>document.getElementById('mySvg');

अब mySvg को SVGSVGElement के रूप में दृढ़ता से टाइप किया गया है।


0

यह एक पुराना विषय है ... शायद 2012 तक मर चुका है, लेकिन रोमांचक और वीएस कोड और टाइपस्क्रिप्ट के लिए नया है।

मुझे निम्नलिखित पैकेज संदर्भों के साथ वीएस कोड में काम करने के लिए यह करना होगा।

const demoCanvas: HTMLCanvasElement = document.getElementById('rfrnCanvas') as any;

        if(demoCanvas.getContext) {
            const context = demoCanvas.getContext('2d');

            if(context) {
                reactangle(context);
            }
        }

टाइपस्क्रिप्ट संस्करण:

{
    "@typescript-eslint/eslint-plugin": "^2.29.0",
    "@typescript-eslint/parser": "^2.29.0",
    "typescript": "^3.7.5"
}


0

आप जोड़ना पड़े DOMको compilerOptions.libअपने में tsconfig.json

// 'tsconfig.json'
 {
  "compilerOptions": {
    "target": "ES2017",
    "module": "commonjs",
    "lib": [
      "es5",
      "DOM",
      "esnext"
    ]
  }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.