1

I am currently discovering TypeScript. I use the following code:

const someClass = document.querySelector(".that-class");    
const someId = document.getElementById("elemId").value;

As many others before me and surely many more to come I am getting the following errors:

Property 'style' does not exist on type 'Element'.
Property 'value' does not exist on type 'HTMLElement'.

I fixed these errors in my .ts file by adding <HTMLElement> or <HTMLInputElement> when needed, works fine. But when I compile my .ts I get some TS warnings from VSCode in the .js file.

My question is simply: is there a way to avoid getting these errors in the JS file as well (i.e.: is there a "cleaner" way to write JavaScript code)? Or should I simply ignore these TS warnings?

Thanks very much for your help!

Stebenwolf
  • 31
  • 7
  • 1
    Does this answer your question? [How to use document.getElementById() method in TypeScript?](https://stackoverflow.com/questions/52491832/how-to-use-document-getelementbyid-method-in-typescript) – depperm Oct 06 '21 at 18:18
  • see also https://stackoverflow.com/questions/33503077/any-difference-between-type-assertions-and-the-newer-as-operator-in-typescript – depperm Oct 06 '21 at 18:18
  • Hi @depperm, thanks for your comment. I've checked both links but unfortunately they do not exactly answer my question. I've already found how to fix the error in the TS file (using f.e. const someId = (document.getElementById("someId"))!.value; or "as HTMLInputElement). After compiling, I get typescript warnings not from the TS file but from the JS file. I could disable the warning with "ts-ignore" but I'm wondering if there's another way to write my code so that I don't get any warning in the JS file as well? – Stebenwolf Oct 06 '21 at 18:33
  • 1
    This answer specifically: https://stackoverflow.com/a/65646512/707111 – Ry- Oct 06 '21 at 22:36
  • @Stebenwolf sorry this comment doesn't answer your question (EDIT: actually maybe it does? Since this won't be removed by the TypeScript compiler), but based on your earlier comment I thought it would be worth recommending against using `as HTMLInputElement` unless you can be absolutely certain that the object you have will definitely be an `HTMLInputElement`, because using a *type assertion* like this effectively bypasses TypeScript's type checking. Instead, you could consider using a *type guard* such as `if (myElement instanceof HTMLInputElement)` to ensure the `value` property will exist. – Mark Hanna Oct 07 '21 at 00:28
  • Hi @Ry- ! thank you for your comment. Although that post didn't specifically solve my issue it helped a lot in my way (stumbled upon it a couple of times so you had it right). Hopefully I found a fix below. Thanks for your help! – Stebenwolf Oct 12 '21 at 09:31
  • 1
    Hi @MarkHanna, thank you very much for your help! As with Ry- I would like to thank you for your comment and research which helped me get through it. I found a fix that I describe below: my issue was that the .value did not exist on the type Element, so I had to find another way to fix it. Feel free to comment the solution, maybe you see things I cannot see yet – Stebenwolf Oct 12 '21 at 09:34

1 Answers1

1

Some good news here: I found the answer I was looking for.

To give you some additional context: I was working with a form and needed to manipulate some user inputs using JavaScript/TypeScript. This is the code:

<form id="my-form" action="index.html" method="get" onsubmit="return showValue();">
    <input type="text" name="username">
    <input type="text" name="full-name">
    <input type="password" name="password">
    <button type="button" onclick="showValue();">Send</button>
</form>

And my JavaScript code:

function showValue() {
    const myForm = document.getElementById("my-form").value;
    console.log(myForm);
    return 1;
}

Which would return the warning: "Property 'value' does not exist on type 'HTMLElement'.

This can easily be fixed by adding some variation of this code in TypeScript:

const myForm = (<HTMLInputElement>document.getElementById("my-form")).value;

Great, no more warning in TypeScript. But after compiling it the resulting JavaScript file would again show the warning: "Property 'X' does not exist on type X"

My question hence was, how do I write my code so that I don't get any warning AT ALL ?

I hopefully found the answer as following:

function showValue() {
    const myForm = document.forms.my-form;
    console.log(myForm?.username.value);
    return 1;
}

It took me quite a while to find it and some digging in specifications docs but hopefully this seems to work!

I still want to thank you all for your comments, they helped a lot in my way to finding the answer.

Stebenwolf
  • 31
  • 7
  • It sounds like you haven't run into it here, but with some linting setups you may get warnings about accessing properties [using square bracket notation](https://eslint.org/docs/rules/dot-notation) when dot notation could have been used instead. One thing I would recommend adding here is a check that `myForm` (and your input) exists before you attempt to access its properties. Depending on your setup, you may be able to use [optional chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining) to do this with only a little code. – Mark Hanna Oct 12 '21 at 19:01
  • Thank you for your comment @MarkHanna (especially the dot notation: I thought it was quite the opposite that was recommended). Optional chaining: if I get it right, "?" checks if the element exists but won't block you, while "!" blocks you if it doesn't? – Stebenwolf Oct 13 '21 at 14:07
  • I've also edited the code to integrate your recommendations - hope I made it right ;) – Stebenwolf Oct 13 '21 at 14:10
  • Sorry @Stebenwolf, I'm a little confused by how you worded that question. If you use optional chaining, i.e. `?.`, then object whose property you are trying to access doesn't exist JavaScript will resolve the expression to `undefined` instead of throwing an error. There is no equivalent `!.` operator, but there is the negation operator `!` and the two inequality operators `!=` and `!==`. You might find the clarity you need from MDN's documentation of [JS operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators) – Mark Hanna Oct 13 '21 at 21:17
  • @MarkHanna My bad, I should have given some more details. I had found that you can use a "!" in typescript that would then disappear after compiling, while the "?" remains in JS. f.e. my TypeScript code: `const myForm = document.forms["my-form"]; console.log(myForm["username"]?.value); console.log(myForm["username"]!.value);` The resulting JS is: `console.log(myForm["username"]?.value); console.log(myForm["username"].value);` NB: I kept the bracket notation here, VSCode throws an error when I write `document.forms.my-form` : `Property 'my' does not exist on type ...` – Stebenwolf Oct 14 '21 at 07:43
  • Edit: the dot notation doesn't work on my document.forms but it actually does on the second line: `const myForm = document.forms["my-form"]; console.log(myForm.username?.value;` – Stebenwolf Oct 14 '21 at 08:24
  • Yeah any property with a dash in it (and other cases like if it contains a space or starts with a number) will need to use square bracket notation instead of dot notation. I'm not familiar with `!.` in TypeScript. It's not the easiest thing to search for, but I've found it is the [Non-null assertion operator](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator). It sounds like it works similarly to `foo as type`, in that it bypasses type checking, so probably one to generally avoid unless it's really necessary to use. – Mark Hanna Oct 14 '21 at 19:30