Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do you remove false error in typescript (error: TS2339)?

var out = document.getElementsByClassName('myclass')[0];
out.focus();
out.select();
out.selectionStart =1;

I'm trying to do this in my typescript file, but for some reason it gives me these errors

ERROR in src/app/main/utilities/keyboard/keyboard.component.ts(29,9): error TS2339: Property 'focus' does not exist on type 'Element'. src/app/main/utilities/keyboard/keyboard.component.ts(30,9): error TS2339: Property 'select' does not exist on type 'Element'. src/app/main/utilities/keyboard/keyboard.component.ts(31,9): error TS2339: Property 'selectionStart' does not exist on type 'Element'.

It is saying that the property does not exist, but it does. When I run this, everything works as it should but I have to do with a huge block of red text in my console which is annoying.

like image 287
Eric Chu Avatar asked Mar 09 '18 19:03

Eric Chu


Video Answer


2 Answers

You need to type cast your out variable to an HtmlElement in order for Typescript to know what methods and properties are available.

var out = document.getElementsByClassName('myclass')[0] as HtmlElement;

You can also do something like this:

(out as HtmlElement).focus();

Or this:

(<HtmlElement>out).focus();

But then you'll have to re-assert the type every time you use out.

Read more about type casting / type assertions here: https://www.typescriptlang.org/docs/handbook/basic-types.html

like image 142
vince Avatar answered Sep 20 '22 01:09

vince


The compiler doesn't know that the Element you are looking at is an HTMLInputElement, so it warns you. If you are positive you are getting an HTMLInputElement, then you can use an assertion like @vincecampanale suggests. Or, you can do something to convince the compiler, like using a user-defined type guard to check:

function isHTMLInputElement(x: Element): x is HTMLInputElement {
  return (x.tagName.toUpperCase() === 'INPUT');
}

var out = document.getElementsByClassName('myclass')[0];

// check that out is really an input element
if (!isHTMLInputElement(out)) 
  throw new Error("My life is a lie");

// from here on out, the compiler is convinced that out is an input element
out.focus(); // okay
out.select(); // okay
out.selectionStart = 1; // okay

The compiler is happy with the above code, because it uses control flow analysis to recognize that the code at and after out.focus() will only run if the type of out is HTMLInputElement. Note that this does not suffer from the issue where you have to keep re-asserting that out is an HTMLInputElement.

Hope that helps.

like image 29
jcalz Avatar answered Sep 19 '22 01:09

jcalz