TypeScript secure coding¶
TypeScript helps developers model expected values, but external data still needs runtime validation. An HTTP body, browser message or API response does not become trustworthy because it is cast to an interface. This guide uses a TypeScript service on Node.js with a bounded pagination limit.
Validate before using the value¶
The application accepts a JSON object whose limit must be an integer from 1 to 100. Call this code after enforcing a request-body size limit and translate validation failures into a client error.
Unsafe: a type assertion only changes the compiler's view.
function readLimit(body: string): number {
const data = JSON.parse(body) as { limit: number };
return data.limit;
}
Safer: check the actual runtime value and its allowed range.
function readLimit(body: string): number {
const data: unknown = JSON.parse(body);
if (typeof data !== 'object' || data === null || Array.isArray(data)) {
throw new Error('Expected an object');
}
const limit = (data as Record<string, unknown>).limit;
if (typeof limit !== 'number' || !Number.isSafeInteger(limit)
|| limit < 1 || limit > 100) {
throw new Error('Limit must be an integer from 1 to 100');
}
return limit;
}
The assertion inside the safer example only permits property inspection after the object check. The following checks establish the actual number constraint. TypeScript's type assertion documentation explains that assertions do not add runtime checks. For larger payloads, use a reviewed schema validator and reject or deliberately strip unexpected fields.
Check the fix¶
Assert that {"limit":25} returns 25. Reject a string value, negative number, fractional number, missing field, array and value above 100. Ensure malformed JSON produces a controlled client response. Test the limit at the database call as well, so a later code change cannot bypass validation.
This validation controls resource use. It does not authorize access to another user's records or make data safe to concatenate into SQL or HTML. Apply parameterized queries, safe DOM sinks and explicit ownership checks at their respective boundaries.
TypeScript and TSX are documented alongside JavaScript. Framework-specific scanner coverage and runtime test coverage remain separate questions; a passing compiler is not a security assessment.