Types Are Enforced at Development Only
A common misconception is that TypeScript provides fault-proof types safety. However, many developers have a deep TypeScript security fallacy in this regard and they do not realize that TypeScript is limited only to development-time type checking. TypeScript types are not enforced at runtime and are stripped away during the compilation process. This compilation process is what turns the rich TypeScript language into its bare-bones JavaScript detail.
TypeScript Types are Stripped Away in Runtime
In the following example we do not use any
type and instead we’re enforcing the string
type for the filterQuery
variable. This is a good practice as it allows TypeScript to enforce type checking at development-time:
class UserController { public getUsers: RequestHandler = async (_req: Request, res: Response) => {
// we now define query as string const filterQuery: string = _req.query.filter as string || '';
const serviceResponse = await userService.findAll({ filter: filterQuery }); return handleServiceResponse(serviceResponse, res); };
If you compile the code with tsc
you’ll see we get no errors or warnings here:
$ npx tsc
What happens if the filter
query string that gets passed to this request handler function as the filterQuery
variable is specified by the user to be used as an array?
The user can launch an HTTP GET request with the []
bracket notation which often is interpeted by HTTP web frameworks like Express on a running Node.js server, that the query string is actually an array and it will indeed be interpreted this way: filter = ['Al']
in the query string example below:
$ curl -X 'GET' -H 'accept: application/json' "http://localhost:8080/users?filter[]=Al"
{ "success": true, "message": "Users found", "responseObject": [ { "id": 1, "name": "Alice", "email": "alice@example.com", "age": 42, "createdAt": "2025-01-13T10:51:37.118Z", "updatedAt": "2025-01-18T10:51:37.118Z" } ], "statusCode": 200}
As you can see, there are no runtime exception or errors thrown even though the filter
query string received a string. The functionality still works because the .toString()
implementation for an Array is to return the first element at position 0.