TypeScript
The safety net that catches bugs before your customers ever see them.
Official Documentation4
integrations
6
documented sections
Overview
TypeScript adds a checking layer on top of JavaScript that catches errors before code ever runs. Developed by Microsoft, it compiles to plain JavaScript, so it works everywhere JavaScript works, and any valid JavaScript is already valid TypeScript, which makes adoption gradual rather than disruptive. The entire modern web stack ships first-class type definitions, including React, Next.js, and NestJS.
Version 6, stable since March 2026, makes strict mode and ES modules the defaults for new projects, turning the practices we already followed into the official baseline.
Strict Mode
Strict mode is the difference between a spell-checker that flags some mistakes and one that flags all of them. It enables the strongest checks TypeScript offers, including strictNullChecks, which forces code to handle missing values, and noImplicitAny, which forbids values with unknown types. TypeScript 6 turns strict mode on by default for new projects, a change we welcomed because we have shipped strict-only code for years. We layer additional checks on top and treat any type error as a build failure.
// tsconfig.json
// TypeScript 6 enables strict mode by default.
// We keep it explicit and add stricter checks on top.
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true
}
}The Type System
TypeScript checks compatibility by the shape of a value rather than its name, an approach called structural typing. Interfaces and type aliases describe object shapes, union types express a value that may be one of several things, and literal types pin a value to an exact constant. The compiler tracks which branch of a union applies at each point in the code, narrowing types as it follows the logic. The payoff is precise modeling: invalid states become impossible to represent, not merely discouraged in a comment.
Generics and Utility Types
Generics let one piece of code work safely with many kinds of data, the way a shipping container carries anything while staying the same shape. A generic function or interface preserves full type information for whatever concrete type flows through it. Built-in utility types such as Partial, Pick, Omit, and Record derive new types from existing ones without redefining fields. We use these tools to define each data model exactly once and reuse it everywhere, so a change in one place updates the whole system.
How Devyst Uses TypeScript
We write all application and infrastructure code in TypeScript under strict mode, with the any type banned outright. Where a type is genuinely unknown, we use the unknown type with a guard that narrows it safely. Component props, API responses, and database models each get explicit interfaces, and shared types live in one directory so the same definition serves client and server. Form input is validated with Zod schemas that produce their own inferred types, so validation and typing can never drift apart.
Tooling and Compilation
The TypeScript compiler checks types and emits JavaScript, though in most Next.js projects the type check runs separately while a faster bundler handles transpilation. The language server powers autocomplete, inline errors, and project-wide refactoring inside the editor. Version 6 standardizes ES modules as the default format, and the TypeScript 7 beta, rebuilt in Go, checks large codebases roughly 10x faster. We run type checking as a required step in continuous integration, so nothing ships with a type error.