Languages & Frameworks
Official siteTypeScript
TypeScript — typed JavaScript that scales; static types as a safety net across frontend, tooling, and shared code.
Overview
TypeScript is my default for any frontend or shared codebase that will live past a demo. Static types turn large refactors from risky into routine, and the type system has grown rich enough to model real domains — generics, discriminated unions, and precise utility types.
I configure TS rigorously: strict mode on, explicit return types, and a typecheck step wired into CI so drift is caught at the gate rather than at runtime. The compiler becomes a tool the team trusts.
In practice TypeScript wraps my React/Vue work and the Node tooling around it, and it makes shared contracts — API clients, domain types — portable across the stack. Good typing is documentation that can not lie.
Strict mode is the baseline, not a suggestion. `strict`, `noImplicitAny`, and the full set of correctness flags let the compiler surface real bugs at build time, which is precisely the point of a typed language layered on a dynamic one.
The type system is expressive enough to model the domain. Discriminated unions make "one of several shapes" explicit, generics keep utilities reusable without losing precision, and utility types map common transformations without hand-writing ceremony.
Shared contracts are where TypeScript compounds. A single typed API client and domain model can be imported by both the client and the server, so a schema change is caught at the line where the contract drifted — not at runtime in production.
TypeScript is the partner of refactoring. Renaming a field, changing a signature, and moving a type are mechanical when the compiler points at every use site, which is why large frontends become safely evolvable rather than frozen by fear of breaking things.
I keep the compiler fast and the config strict but pragmatic: incremental builds, isolated modules where they pay, and no `any` leaking at the seams. The team gets a safety net that helps rather than a fight with the tooling.
Where JavaScript is a lighter touch, I still serialize typed contract files so the boundary stays honest. TypeScript is not about typing everything forever — it is about not trusting the seams where correctness actually matters.
How I Work With TypeScript
I start from strict mode. `strict`, `noImplicitAny`, and the correctness flags are on from day one, so the compiler surfaces real bugs at build time.
Return types are explicit. I annotate function return types so the contract is readable and drift is caught, rather than inferred silently.
The type system models the domain. Discriminated unions, generics, and utility types describe "one of these shapes" precisely, so the code reads like the domain it represents.
Shared contracts are typed once and reused. An API client and domain model imported by both client and server catch a drifted schema at the type-checking line rather than at runtime.
I keep types honest at the seams. No leaks of `any` at boundaries — where a boundary is untyped (a third-party API), I define the contract explicitly instead of trusting silence.
Typechecking is wired into CI as a hard gate. The command fails the build if the types break, so regressions are caught before they reach production.
The compiler stays fast. Incremental builds and isolated modules keep the safety net helpful rather than a fight with tooling.
Refactoring is mechanical. Renaming a field or changing a signature lights up every use site, which is what makes large frontends safely evolvable.
Where plain JavaScript is the lighter fit, I still serialize typed contract files so the boundary stays honest — TypeScript is about not trusting the seams, not about typing everything forever.