Write a generic TypeScript handler for mixed form inputs?
Tests TypeScript DOM narrowing. Strong answer: union-type ChangeEvent, narrow target with instanceof or tag checks, branch on element.type to read .checked for checkboxes or .value otherwise. Red flag: casting to any or assuming all inputs use .value.
What's really being asked
This question tests whether you can use TypeScript narrowing to handle real DOM API differences without falling back to any. Interviewers want to see that you understand HTMLInputElement, HTMLSelectElement, and HTMLTextAreaElement have overlapping but not identical interfaces, and that you know how to refine a union type inside an event handler. It also reveals if you understand the difference between event target and currentTarget in the DOM.
The full answer
First, the candidate should type the event as a union, for example ChangeEvent of HTMLInputElement or HTMLSelectElement, or a generic E extending ChangeEvent of HTMLElement. Second, they should narrow the target using a type guard such as instanceof HTMLInputElement, checking element.tagName, or checking the element.type property. Third, they should branch on whether the element is a checkbox or radio button, reading .checked for those, and .value for text inputs, selects, and textareas. Fourth, a senior candidate might mention using a configuration map keyed by input name that encodes the expected type, keeping the handler generic while preserving type safety through a discriminated union or mapped type.
The mistakes people make
The biggest red flag is casting event.target to any or using a type assertion to HTMLInputElement on every branch. Another mistake is assuming all form elements have .value and reading it from a checkbox, which silently gives the string on instead of a boolean. Some candidates write separate handlers for every input and miss the point of the exercise entirely. Using unknown without a proper guard chain is slightly better but still weak if it ends in a blind type assertion.
What usually comes next
The interviewer might ask how you would type this in React versus vanilla DOM, or how to store the resulting state in a single object without losing type information. They might also ask how to make the handler work with a dynamic list of fields where each field has a different TypeScript type, which pushes toward generics, keyof, or mapped types. Another variant is asking how to handle custom components that forward refs and events.
A concrete example
Imagine a form with username as text, country as select, and subscribe as checkbox. The handler receives a ChangeEvent. You check if event.target instanceof HTMLInputElement. If true, you check if target.type equals checkbox. If so, you store target.checked as boolean. Otherwise you store target.value as string. If the target is an HTMLSelectElement, you store target.value as string. This keeps every branch type-safe and compiles without resorting to any.
Interview question
When building a single TypeScript handler for mixed form inputs, which strategy correctly preserves type safety when extracting values from checkboxes, text inputs, and selects?
- a.Rely on event.currentTarget because it always refers to the specific input that triggered the event.
- b.Narrow event.target with instanceof checks and branch on element.type to read .checked or .value.Correct
- c.Cast event.target to any and use a configuration map to decide which property to read.
- d.Type the event as ChangeEvent<HTMLInputElement | HTMLSelectElement> and read event.target.value on every branch.
Why? this is the answer
Narrowing with instanceof and branching on element.type lets the compiler verify you read .checked for checkboxes and .value for other elements. Option D is tempting because it uses a union type, but reading .value from a checkbox gives the string on rather than the boolean state, breaking both type safety and runtime logic.
Just read this? Test yourself on what you have been reading.
Read the original → typescriptlang.org
- #typescript
- #dom
- #narrowing
- #event-handlers
- #generics
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on typescript — each one lists the topics its interview covers.
See open roles