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.
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.
const textInput = document.querySelector<HTMLInputElement>('#username');
if (textInput === null) throw new Error('Input not found');
const username: string = textInput.value; // always stringEven 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.
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.
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.
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.
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:
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 |
|---|---|---|---|---|
| Empty | empty string | NaN | null | false |
| Filled | entered string | parsed number | parsed Date | true 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
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.
Frequently Asked Questions
Why is input.value always a string in TypeScript?
How do I read a checkbox value in TypeScript?
How do I handle file inputs in TypeScript?
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.
More in this topic
TypeScript Compiler Explained
The TypeScript compiler (tsc) turns .ts files into .js files while checking types. Learn what it does, how to use it, and how it fits your workflow.
Set Up ESLint for TypeScript
Install and configure ESLint with typescript-eslint to catch bugs and enforce consistent code style in your TypeScript project.
Pick Utility Type in TypeScript
Pick creates a new type by selecting only the properties you name from an existing type. Use it to build focused types for specific views, API responses, or function parameters.