Why do you have to validate input on the server even though TypeScript already has types?
Suggested answer
The interviewer wants to know whether you can tell compile-time types apart from real data at runtime, and whether you think about the fact that data from outside can't be trusted.
TypeScript types only exist while you write and compile code. When the program runs, the types are erased, so JSON.parse(body) returns whatever the sender put in, and writing as Order is only you making a promise to the compiler, not a check. Data from a request, a file or another API is untrusted until it has been validated.
What happens when you don't validate:
- Silent errors. A quantity that is text makes the multiplication come out as
NaN, which becomesnullwhen converted to JSON, and the total is wrong without any error. - Errors that spread. A record missing a field makes the processing function throw, and if that function runs over a whole list, one bad record breaks it for everyone.
- Security holes. The sender can also set fields they shouldn't be allowed to set, such as
idor permissions.
The right approach is to validate right where data enters the system, with a schema library such as Zod: declare the valid shape, call safeParse, and if it fails return a 400 with the list of errors per field. After that step, the rest of the code uses the type inferred from the schema and trusts it. Declare incoming data as unknown instead of any, so the compiler forces you to check it before you use it.
An important point to make: validate once at the door, not scattered everywhere, and tell errors caused by the sender (400) apart from errors of the server (500).
Bonus points: mention limiting the size of the body that can be sent, and deciding whether to allow unknown fields (rejecting them outright is usually safer than silently ignoring them).