TypeScript Interfaces Do Not Provide Type Safety
TypeScript interfaces are a way to define the shape of an object and they’re pretty commonly used through-out any real-world projects and production applications. However, they may also give a false sense of security when types are more structured and complex in this way - a formal interface.
TypeScript Interfaces Are Not Enforced at Runtime
Section titled “TypeScript Interfaces Are Not Enforced at Runtime”TypeScript expects to uphold the following generic interface which you may recognize from the Express.js library for handling HTTP requests:
(alias) interface Request<P = core.ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = qs.ParsedQs, Locals extends Record<string, any> = Record<string, any>> import RequestLet’s say you’re building on-top of this HTTP function handler interface, as follows:
interface UserComponentQueryString { name?: string;}
class UserController {
public getUserHelloComponent: RequestHandler = async ( _req: Request<{}, {}, {}, UserComponentQueryString>, res: Response) => {
const userName = _req.query.name || "World";
const helloComponent = `<h1>Hello, ${userName}!</h1>`; return res.send(helloComponent); }}What happens if the name query parameter is not a string? What if it’s an array of strings or an object? TypeScript interfaces do not provide type safety at runtime, so the following request will still be evaluated as-is by the Express route handler:
$ curl -G -X 'GET' -H 'accept: application/json' "http://localhost:8080/users/component" --data-urlencode "name[]=<img src=x onError=alert(1) />"
<h1>Hello, <img src=x onError=alert(1) />!</h1>