Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I solve 'Property 'width' does not exist on type 'HTMLElement'.' when type checking Javascript (NOT Typescript) using // @ts-check in vscode?

In the view.js file:

const canvas = document.getElementById('canvas');
...
export {
  canvas,
}; 

in the main.js file:

 import * as view from '../src/view.js';
 ...
 xPosition: view.canvas.width / 2,

gives me 'Property 'width' does not exist on type 'HTMLElement'. type checking error.

I don't know how to proceed, I have zero knowledge of typescript, and the program is written in javascript anyway. All the solutions I have read require using typescript, which is useless in this example.

Is there anything I can do to get rid of this error?

EDIT if I add the following:

/** @type {HTMLCanvasElement} */
const canvas = document.getElementById('canvas');

in my view.js file it fixes all the errors in my main.js... BUT, when I add // @ts-check on the view.js file that contains the above line I get:

Type 'HTMLElement' is not assignable to type 'HTMLCanvasElement'.
  Property 'height' is missing in type 'HTMLElement'.

EDIT 2

I seemed to have solved that with adding some brackets using the following line:

const canvas = /** @type {HTMLCanvasElement} */ (document.getElementById('canvas'));
like image 697
Sumomo Avatar asked Feb 24 '18 18:02

Sumomo


1 Answers

Not all HTML elements have a width, although the canvas does. You can solve the issue by narrowing the type from HTMLElement to HTMLCanvasElement (code example taken from this TypeScript article).

const canvas = document.getElementById('x');

if (isCanvas(canvas)) {
    const width = canvas.width;
}

function isCanvas(obj: HTMLCanvasElement | HTMLElement): obj is HTMLCanvasElement {
    return obj.tagName === 'CANVAS';
}

Or you can cheat with a type annotation:

const canvas = <HTMLCanvasElement>document.getElementById('x');
const width = canvas.width;

In JavaScript you can use JSDoc comments to perform type assertions:

/**
 * @type {HTMLCanvasElement}
 */
const canvas = document.getElementById('x');

And, though I haven't tried it, you might get away with a ts-ignore comment even though it is a JavaScript file:

// @ts-ignore: I don't care that it might not be a HTML Canvas Element
const width = canvas.width;
like image 83
Fenton Avatar answered Sep 28 '22 07:09

Fenton