DEV Community

rashidpbi
rashidpbi

Posted on

πŸš€ A Practical Guide to TypeScript in Next.js (For Real-World Devs)

I recently dove deep into integrating TypeScript with a Next.js project, and while the official docs are helpful, I wanted to consolidate my understanding in a way that actually clicks β€” for myself and for anyone else walking the same path. This post captures everything I wish I'd known earlier: not just the how, but also the why behind TypeScript's behavior in a Next.js setup.

πŸ”§ Setting Up TypeScript in a Next.js Project

If you're starting from scratch, here's how to set up TypeScript with a Next.js app:

1. Create a Next.js Project

npx create-next-app@latest my-next-app
cd my-next-app
Enter fullscreen mode Exit fullscreen mode

2. Install TypeScript and Type Definitions

pnpm add -D typescript @types/react @types/node
# or
npm install -D typescript @types/react @types/node
Enter fullscreen mode Exit fullscreen mode

3. Run the Dev Server

When you run pnpm dev or npm run dev, Next.js detects TypeScript and automatically generates a basic tsconfig.json for you. You don't need to configure compilation separately β€” Next.js handles that under the hood.

πŸ€– So… What Does TypeScript Actually Do?

TypeScript brings static typing to JavaScript. Think of it as a spell checker for your logic. It catches errors like these:

let age: number = "25"; // ❌ Error: Type 'string' is not assignable to type 'number'
Enter fullscreen mode Exit fullscreen mode

This kind of feedback before running your app is what makes TS shine β€” especially as your codebase grows.

🧠 End Goal of Using TypeScript?

After proper integration, your TypeScript setup should:

βœ… Catch bugs before runtime

βœ… Improve code readability and maintainability

βœ… Boost IDE features like autocomplete and refactoring

βœ… Make large projects safer to work on (hello, refactors!)

And the best part? You don't need to run any special build command for TS in Next.js. The framework handles compilation transparently.

πŸ”„ Does TypeScript Compilation Actually Happen?

Yes, but you rarely see it directly.

  • In dev mode (pnpm dev), TypeScript is compiled on the fly.
  • In production builds (pnpm build), Next.js compiles everything to pure JavaScript inside the .next/ directory.

So ultimately, browsers only see JavaScript. TypeScript helps us during development and build time.

❓ Do You Need to Manually Compile .ts Files?

Nope. Not in Next.js.

If you're curious, you can compile TS with tsc manually in plain TypeScript projects, but with Next.js, it's all baked in.

🧩 Type Errors & Editor Support

Does TS stop you from assigning wrong types?

Yes, and that's its superpower.

function greet(name: string) {
  return "Hello, " + name;
}

greet(42); // ❌ Error: Argument of type 'number' is not assignable to type 'string'
Enter fullscreen mode Exit fullscreen mode

Does this error handling come from a VS Code extension?

No. VS Code has built-in TypeScript support β€” you get error squiggles, IntelliSense, and quick fixes out of the box. Extensions like ESLint or Prettier can enhance it, but aren't necessary to use TypeScript.

🧾 What Is tsconfig.json and Do You Need It?

The tsconfig.json file is TypeScript's configuration brain. While VS Code can run without it, having one:

πŸ“ Controls which files to include/exclude

πŸ” Enables strict type checking

✨ Supports path aliases (e.g. @/components)

Example config:

{
  "compilerOptions": {
    "strict": true,
    "jsx": "preserve",
    "moduleResolution": "node",
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
    "noEmit": true
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}
Enter fullscreen mode Exit fullscreen mode

πŸ“„ What Are Type Declaration Files (.d.ts)?

A Type Declaration File is like telling TypeScript:

"Hey, this function/variable exists β€” trust me β€” and here's what its type looks like."

Use case:

You're working with a global JavaScript library that's not typed.

Example:

// global library: myLib.js
myLib.makeGreeting("hello");
Enter fullscreen mode Exit fullscreen mode

Instead of TS screaming at you, you declare its shape:

// global.d.ts
declare namespace myLib {
  function makeGreeting(s: string): string;
  let numberOfGreetings: number;
}
Enter fullscreen mode Exit fullscreen mode

Now TypeScript understands how to treat myLib.

Bonus: Overloaded Functions

TS can also handle functions that behave differently based on input:

declare function getWidget(n: number): Widget;
declare function getWidget(s: string): Widget[];
Enter fullscreen mode Exit fullscreen mode

So getWidget(1) returns one widget, and getWidget("all") returns an array.

βœ… Final Words

TypeScript isn't about writing more code β€” it's about writing safer code. In a modern stack like Next.js, it integrates seamlessly, improves DX (Developer Experience), and saves you from a ton of head-scratching bugs down the line.

If you're still unsure whether to go all-in with TS, try enabling it in just one file β€” you might not go back.

Top comments (0)