javascriptvisual-studiojavascript-intellisense

Lacking IntelliSense with Visual Studio when writing JavaScript


I am trying to learn JavaScript and write a few examples in Visual Studio. But Intellisense stops working for me when getting the context for a canvas. The example renders fine in the browser.

<!DOCTYPE html>
<html>
<head>
    <title>Canvas with text</title>
    <meta charset="utf-8" />
</head>
<body>
    <canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
        Your browser does not support the HTML5 canvas tag.
    </canvas>
    <script>
        var c = document.getElementById("myCanvas");
        var ctx = c.getContext("2d");
        ctx.font = "30px Arial";
        ctx.fillText("Hello World", 10, 50);
    </script>
</body>
</html>

The line: "var ctx = c.getContext("2d");" results in ctx not getting IntelliSense. So font and fillText are properties and methods that I just kind of have to know in advance, not getting any help from Visual Studio.

Is that normal or am I doing something wrong?


Solution

  • Unfortunately this is expected.

    Visual Studio uses typescript under the hood to statically analyze your code and guess what 'type' your working with, and therefore provide intellisense. This is no easy task; JavaScript isn't a typed language, and frankly it's impressive that VS does this well.

    However, the .getContext() function can return a few different types (https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext), and CanvasRenderingContext2D is only one of them. And while we can appreciate that your string '2d' is a constant, tsc can't.

    There's some hope- VS also remembers things you've done on an object, so once you've used a few properties it'll start suggesting those (although, frankly, that's bit of a double-edge sword if you misspell something!).

    CanvasRenderingContext2D doesn't appear to have a constructor (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D), which means you can't hint to tsc what you were hoping for. This is fairly common, I'm afraid.

    The only alternatives I can suggest is to use TypeScript directly, or consider adding Flow to your project which allows you to use JavaScript and annotate types (inc. a vscode extension which can make sense of these).