52

I have a checkbox on my html file.

<input id="is3dCheckBox" type="checkbox" checked="checked" />

and I want to know in the .ts file if this checkbox is checked or not.
What cast should be done after I get this element in order to check it?

4 Answers 4

87

You just need to use a type assertion to tell TypeScript it is an HTMLInputElement:

var element = <HTMLInputElement> document.getElementById("is3dCheckBox");
var isChecked = element.checked;

Update:

Any ideas why var element = document... works but var element: HTMLInputElement = document... does not?

When you use getElementById the element returned could be any kind of HTML element. For example, it could be a paragraph tag. For this reason, the type definition for this DOM method returns a very general HTMLElement type.

When you try the following:

var element: HTMLInputElement = document.getElementById('is3dCheckBox');

The compiler warns you that the result of getElementById is not an HTMLInputElement, or a sub-type of HTMLInputElement (because it is actually a super-type of the one you want).

When you know the element type, it is perfectly normal to use a type assertion to tell the compiler the type. When you use the Type Assertion, you tell the compiler you know better.

In some cases, the compiler will still warn you when using a type assertion, because it can tell that the assertion is likely to be a mistake - but you can still force it, but widening the type first:

var isChecked = (<HTMLInputElement><any>myString).checked;

The string variable is widened to the any type, before asserting the HTMLInputElement. Hopefully you won't need to use this kind of type assertion too often.

Sign up to request clarification or add additional context in comments.

3 Comments

Any ideas why var element = <HTMLInputElement> document... works but var element: HTMLInputElement = document... does not? Also, I couldn't find this syntax on the TS Handbook, care to point your source?
@Kostas, the solution provided by Fenton is not a standard way of handling the task you're trying to accomplish. The solution is pure Javascript (but type casted to HTMLInputElement for typescript), that's the reason you aren't able to find it in the TS Handbook.
@Kostas you'll find it in the handbook under "Basic Types" -> "Type Assertions". This is part of the TypeScript language specification, and is recommended for situations where you know more about the type than the compiler: typescriptlang.org/docs/handbook/…
3

If you use tsx files like i did you cant use the angle bracket sintax, you have to use "as"

  let element  =  document.getElementById("is3dCheckBox") as HTMLInputElement; 
  if(element.checked){
    // TODO
  }

you can read more here https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-assertions

Comments

2

For documet.getElementById you can use:

let element = <HTMLInputElement> document.getElementById("is3dCheckBox");  
if (element.checked) { you code }

For documet.getElementsByName you can use:

let element = <any> document.getElementsByName("is3dCheckBox");  
if (element.checked) { you code }

Comments

0

I will offer an alternative to the top rated answer. Using a type assertion could lead to errors and somewhat defeats the purpose of using typescript.

The return type for Document.getElementById is HTMLElement | null so how can you guarantee that the return type is a checkbox when the creators of the function definition could not guarantee such action. What if somebody makes typo or changes the checkbox to a select element?

First, create a CheckboxElement type:

interface CheckboxElement extends HTMLInputElement {
  type: "checkbox";
}

Then create a function to narrow down the type received from getElementById:

function toCheckbox(
  element: HTMLElement | null
): CheckboxElement | null {
  const checkbox = element as CheckboxElement;
  return checkbox?.type.toLowerCase() === "checkbox" ? checkbox : null;
}

Then, use the function like this:

const element = document.getElementById("is3dCheckBox");
const checkbox = toCheckbox(element)
if (!checkbox) {
  // handle not a checkbox however you like;
  console.error("not a checkbox");
  return;
}
const isChecked = checkbox.checked;

This does add more code and using a type assertion could be preferable depending on the circumstances. I prefer to use type assertions only in test code.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.