DevConnectDevConnect
Sign up · Log in

TypeScript where it earns its keep

Types at the boundaries, what any costs you, and when to stop.

16 min read

The track name says TypeScript, and the question in practice is not whether to use it but where to spend the effort.

Types belong at the boundaries. The value of a type is highest where data enters your program: an API response, a form submission, a URL parameter, something read from storage. Inside a function that you wrote and that only you call, inference usually says everything worth saying. Annotating every local variable produces noise without catching anything.

`any` switches off the checker. It does not mean "some type"; it means "stop checking from here". One any at the edge of a module quietly removes the guarantees from everything downstream of it. Where a type is genuinely unknown, unknown is the honest choice: it forces you to narrow before use, which is exactly the check you wanted.

The API response is not what the type says. A type is a claim about data you have not seen. const user = await res.json() as User asserts rather than verifies, and if the server changes a field the failure surfaces somewhere else entirely, as undefined is not a function. Validate at the boundary with a schema, or narrow by hand, and the failure appears where it belongs.

Unions describe reality better than optional fields. A request is loading, or it failed, or it succeeded with data. Modelling that as { loading: boolean; error?: Error; data?: User } allows states that cannot happen and forces checks that cannot be removed. A discriminated union rules them out: the compiler then knows that data exists in the success branch.

When to stop. If a type is harder to read than the code it describes, it is doing less work than it costs. Types are there to make wrong code fail early, not to be clever.

Go deeper

Lessons are not assessed. Progress towards the certificate is recorded from the work you submit. See all requirements