Type Input Values in TypeScript

Learn how to read and type input values in TypeScript. Handle .value, .checked, .valueAsNumber, .valueAsDate, and different input types correctly.

7 min read

Every input element shares the HTMLInputElement interface, which is how you type input values in TypeScript. Its .value property is always a string, regardless of the input type.

For checkboxes, radios, number inputs, date inputs, and file inputs, there are additional properties that give you the value in a more useful form. Knowing which property to use for each input type keeps your form handling code clean and type-safe.

The .value property

HTMLInputElement.value is always typed as string. This is true even for number inputs because the DOM stores everything as a string internally. Whether you are reading a text field, an email input, or a password field, the value is a string.

typescripttypescript
const textInput = document.querySelector<HTMLInputElement>('#username');
if (textInput === null) throw new Error('Input not found');
 
const username: string = textInput.value; // always string

Even a number input returns a string from .value. If you need a number for calculations, use the .valueAsNumber property instead or parse the string yourself with Number. Relying on .value for numeric data will lead to string concatenation bugs.

valueAsNumber for numeric inputs

For number inputs and range inputs, use .valueAsNumber to get the value as a number. This property parses the string automatically and returns a proper JavaScript number.

typescripttypescript
const ageInput = document.querySelector<HTMLInputElement>('#age');
if (ageInput === null) throw new Error('Input not found');
 
const age: number = ageInput.valueAsNumber;
//    ^? const age: number
 
console.log(age + 10); // OK, numeric addition

.valueAsNumber returns NaN when the input is empty or contains non-numeric text. Always validate with Number.isNaN before using the result in calculations. An empty number input is a common edge case that .valueAsNumber handles by returning NaN rather than throwing.

valueAsDate for date and time inputs

For date, time, and datetime-local inputs, use .valueAsDate to get a Date object. This is far more useful than the formatted string from .value when you need to do date arithmetic or format the date differently.

typescripttypescript
const startDateInput = document.querySelector<HTMLInputElement>('#start-date');
if (startDateInput === null) throw new Error('Input not found');
 
const startDate: Date | null = startDateInput.valueAsDate;
 
if (startDate !== null) {
  console.log(startDate.getFullYear()); // e.g., 2026
  console.log(startDate.toISOString());
}

.valueAsDate returns null when the input is empty. This is different from .value which returns an empty string. The null check is essential because calling Date methods on null would throw at runtime.

.checked for checkboxes and radios

Checkboxes and radio buttons use .checked to represent their state, not .value. The .checked property is a boolean that tells you whether the box is ticked or the radio is selected.

typescripttypescript
const agreeCheckbox = document.querySelector<HTMLInputElement>('#agree');
if (agreeCheckbox === null) throw new Error('Checkbox not found');
 
const agreed: boolean = agreeCheckbox.checked;
//    ^? const agreed: boolean
 
if (agreed) {
  console.log('User agreed to terms');
}

The .value property on a checkbox is a different thing entirely: it is the string value that gets sent to the server when the form is submitted with the box checked. Do not read .value to determine if a checkbox is ticked. Always use .checked for that.

File inputs

File inputs expose selected files through the .files property, typed as FileList or null. When the user has not selected any files, .files is null or has zero length.

typescripttypescript
const fileInput = document.querySelector<HTMLInputElement>('#avatar');
if (fileInput === null) throw new Error('Input not found');
 
const files: FileList | null = fileInput.files;
 
if (files !== null && files.length > 0) {
  const firstFile: File = files[0];
  console.log(firstFile.name); // e.g., 'photo.jpg'
  console.log(firstFile.size); // bytes
  console.log(firstFile.type); // e.g., 'image/jpeg'
}

For multiple file uploads, loop through files with a for-of loop. Each file in the iteration is typed as File, giving you .name, .size, .type, and .lastModified automatically.

Reading input values on events

When handling input or change events, TypeScript still types event.currentTarget as EventTarget or null, even though you attached the listener to a known HTMLInputElement. The simplest fix is to read the outer variable directly through the closure instead of the event object:

typescripttypescript
const nameInput = document.querySelector<HTMLInputElement>('#name');
if (nameInput === null) throw new Error('Input not found');
 
nameInput.addEventListener('input', () => {
  console.log(nameInput.value); // current text as the user types
});

Avoid reading event.target.value directly because event.target is typed as EventTarget or null, which does not have .value. If you need the value from the event object itself rather than the closure, assert the type: const input = event.currentTarget as HTMLInputElement.

Empty input handling

Different input properties handle empty states differently. Knowing the behaviour of each helps you write correct validation logic.

Input state.value.valueAsNumber.valueAsDate.checked
Emptyempty stringNaNnullfalse
Filledentered stringparsed numberparsed Datetrue or false

Always check for empty values before using them in calculations or API calls. An empty string is falsy but not null, and NaN does not compare equal to anything including itself, so use Number.isNaN for numeric validation.

See Type Form Elements in TypeScript for form-wide typing patterns. See Type Event Handlers in TypeScript for event handling details.

Rune AI

Rune AI

Key Insights

  • HTMLInputElement.value is always a string, regardless of the input type.
  • Use .checked (boolean) for checkboxes and radio buttons, not .value.
  • Use .valueAsNumber for numeric inputs like type number or type range.
  • Use .valueAsDate for date and time inputs to get a Date object.
  • Always check for null and empty strings before processing input values.
RunePowered by Rune AI

Frequently Asked Questions

Why is input.value always a string in TypeScript?

The DOM spec defines HTMLInputElement.value as a string. Even for numeric input types, the .value property is always a string. Use .valueAsNumber to read it as a number, or parse it with Number or parseInt for calculations.

How do I read a checkbox value in TypeScript?

Checkbox inputs use the .checked property (boolean), not .value. The .value property on a checkbox is the string sent when the form is submitted and the box is checked. Use .checked to detect whether the box is actually ticked.

How do I handle file inputs in TypeScript?

HTMLInputElement.files returns FileList or null. Use input.files with optional chaining and index 0 to get the first selected file. The File type gives you .name, .size, .type, and .lastModified.

Conclusion

TypeScript types every input property through the HTMLInputElement interface. .value is always a string, .checked is boolean for checkboxes, .valueAsNumber gives numbers, and .valueAsDate gives Date objects. Always guard against null and empty strings before using input values.