TypeScript · Types that pay for themselves
What TypeScript practices do you follow in production?
Short answer
Prefer inference for locals and explicit types at boundaries, keep types narrow, avoid any, enable strict mode and validate untrusted data at runtime. Model states with discriminated unions.
Good TypeScript is less about clever type gymnastics and more about making invalid states hard to represent. The compiler should enforce the important contracts, while the code stays readable for the next person. Types are documentation that cannot drift silently.
- Enable strict mode and fix errors with narrowing, not assertions
- Annotate public APIs, exported functions and shared data shapes
- Let local variables and simple callbacks be inferred
- Use unknown plus validation for external data instead of any
- Model finite states with discriminated unions and check them exhaustively
- Keep generics only where they preserve a real relationship
- Avoid deep conditional types unless they remove meaningful duplication
type Result<T> =
| { ok: true; value: T }
| { ok: false; error: string };
function parseUser(input: unknown): Result<{ id: number }> {
if (
typeof input === "object" &&
input !== null &&
"id" in input &&
typeof input.id === "number"
) {
return { ok: true, value: { id: input.id } };
}
return { ok: false, error: "Invalid user" };
}This example combines several practices: unknown at the boundary, a runtime check, a discriminated result and a precise success type. Callers must handle both branches, and the success branch carries the validated value. The type is doing real work rather than decorating the code.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Why prefer unknown over any at boundaries?
- 2When do you annotate a return type?
- 3How do you keep types readable for a team?
- 4When is a complex conditional type justified?
Say it in the interview
My defaults are strict mode, inference for locals, explicit types at public boundaries, and unknown plus validation for external data. I model finite states with discriminated unions and use never for exhaustiveness. I avoid any and heavy type gymnastics unless they remove real duplication. The goal is types that make invalid states hard to represent and errors easy to understand.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live TypeScript mock interview and get scored feedback on depth, clarity and confidence.