Best Practices & Next Steps
Pull together everything you've learned with real-world TypeScript best practices: strict mode, project setup, third-party types, linting, and migration.
Introduction
You've now covered TypeScript's core type system — from basic types through generics, enums, and narrowing. This final lesson focuses on the practical, real-world side: how to configure a project well, work with the wider ecosystem, and where to go from here.
- How to configure and roll out strict mode effectively.
- How to structure a TypeScript project's tsconfig.json for real work.
- How to get types for third-party JavaScript libraries.
- How linting and formatting tools fit alongside the compiler.
- How to migrate an existing JavaScript codebase to TypeScript gradually.
Configuring Strict Mode
The single `"strict": true` flag in tsconfig.json actually bundles together a whole family of checks: `strictNullChecks` (null and undefined must be handled explicitly), `noImplicitAny` (every value must have a known type), `strictFunctionTypes`, and several others. Turning strict mode on catches dramatically more real bugs, and it is far easier to start a project strict than to retrofit it onto a large, already-loose codebase later.
Project Structure and tsconfig
A well-organized tsconfig.json typically separates source from compiled output using `rootDir` and `outDir`, limits compilation scope with `include`/`exclude`, and can define path aliases so imports like `@/components/Button` resolve cleanly instead of long relative paths like `../../../components/Button`.
{ "compilerOptions": { "strict": true, "target": "ES2020", "rootDir": "src", "outDir": "dist", "baseUrl": ".", "paths": { "@/*": ["src/*"] } }, "include": ["src"], "exclude": ["node_modules", "dist"]}Working with Third-Party Types
Many npm packages ship their own type declarations (.d.ts files) built in, so importing them just works with full autocomplete. For older or plain-JavaScript-only packages, the community-maintained DefinitelyTyped project publishes matching type packages under the `@types/` scope.
# For a library without built-in typesnpm install --save-dev @types/lodashLinting and Formatting
The TypeScript compiler checks types, but doesn't enforce style or catch every code-quality issue. ESLint with the `@typescript-eslint` plugin adds type-aware linting rules (like flagging unused variables or unsafe `any` usage), while Prettier handles automatic code formatting — the two are commonly used together, running alongside `tsc` in CI.
TypeScript with Frameworks
React components are typically written in `.tsx` files, typing props with an interface. Next.js has TypeScript support built in with zero configuration. Node.js backends add `@types/node` (and `@types/express` for Express) for full typings of the runtime and framework APIs. Angular is TypeScript-first by design, and modern runtimes like Deno and Bun understand TypeScript natively, with no separate compile step required during development.
interface ButtonProps { label: string; onClick: () => void;}
function Button({ label, onClick }: ButtonProps) { return <button onClick={onClick}>{label}</button>;}Migrating JavaScript to TypeScript
You do not need to convert an entire codebase at once. The standard approach is incremental: enable `allowJs` and `checkJs` so TypeScript can type-check plain .js files using JSDoc comments, then rename files from .js to .ts one at a time, starting with the most-used, most-stable modules. Many teams start with a looser tsconfig on legacy code, then tighten `strict` settings gradually as more of the codebase is converted.
Common Mistakes
- Enabling every strict flag on a large legacy codebase all at once, producing thousands of errors instead of migrating incrementally.
- Reaching for `@ts-ignore` to silence a compiler error instead of understanding and fixing the actual underlying issue.
- Skipping `@types/*` packages for third-party JavaScript libraries, quietly losing type safety at every call into that library.
- Never actually running `tsc --noEmit` in CI, treating TypeScript as documentation rather than an enforced, automated check.
Best Practices
- Run `tsc --noEmit` in CI so type errors block a merge, exactly like a failing test would.
- Keep `@types/*` packages updated alongside the libraries they describe.
- Adopt strict mode as early as possible — even mid-migration, new files can be strict while older files are grandfathered in.
- Treat compiler complaints as a collaborator catching a real bug, not an obstacle to silence.
Frequently Asked Questions
Practice TypeScript inside a real framework — React with .tsx, Next.js, or Node with Express — and get comfortable with the utility types (Partial, Pick, Omit, Record) covered in the generics lesson.
No — if a library ships its own .d.ts files (increasingly the norm), you get full types automatically with no extra install.
Yes — that is the standard, recommended approach: enable allowJs, rename files incrementally, and tighten strict checks over time rather than converting everything at once.
Yes — most professional frontend and Node.js backend roles today expect TypeScript, and it catches an enormous class of real bugs before they ever reach production.
Key Takeaways
- `"strict": true` bundles the checks that catch the most real bugs — enable it from day one on new projects.
- A well-structured tsconfig.json separates source and output and can define clean import path aliases.
- @types/* packages from DefinitelyTyped provide types for JavaScript-only libraries.
- ESLint (with @typescript-eslint) and Prettier complement, rather than replace, the TypeScript compiler.
- Large JavaScript codebases can migrate to TypeScript incrementally, file by file, without a risky rewrite.
Summary
Congratulations — you've completed the TypeScript course, from what TypeScript is and why Microsoft built it, through the full type system, object-oriented programming, generics, and now real-world project practices. The best next step is to build something real: add TypeScript to a small project, turn on strict mode, and let the compiler guide you as you go.