Next.js 16 Type Safety: Async PageProps & Typed Routes

Published: (December 22, 2025 at 03:57 PM EST)
3 min read
Source: Dev.to

Source: Dev.to

Introduction

Next.js has quietly become one of the most type‑safe full‑stack frameworks, yet many teams only use a fraction of its capabilities. This post walks through practical, production‑ready type‑safety features in the modern App Router, including:

  • TypeScript checker enhancements
  • Statically typed links
  • Route‑aware type helpers
  • Auto‑complete for environment variables
  • Typed NextRequest and NextResponse

This is not a beginner guide; it focuses on features that prevent bugs in real‑world applications.

TypeScript Checker

Next.js ships with a custom TypeScript plugin that extends the default tsc checks. It understands Next.js‑specific concepts such as:

  • File‑based routing
  • Server vs. client components
  • Metadata APIs
  • Layout and page conventions

Enabling the plugin in VS Code

  1. Open the Command Palette (Ctrl/Cmd + Shift + P).
  2. Search for TypeScript: Select TypeScript Version.
  3. Choose Use Workspace Version.

VS Code will now pick up the Next.js‑specific type rules automatically via next-env.d.ts, giving you IntelliSense and in‑context documentation for APIs like metadata and caching options.

Additional checks provided by the plugin

  • Correct usage of the "use client" directive.
  • Prevention of client‑only hooks (e.g., useState) in Server Components.
  • Detection of invalid exports in page.tsx, layout.tsx, and route.ts.

Next.js can generate statically typed routes to eliminate typos and invalid navigation.

Enable typed routes

// next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  typedRoutes: true,
};

export default nextConfig;

When typedRoutes is enabled, Next.js creates route definitions inside .next/types. TypeScript then validates links and navigation at compile time, providing:

  • Compile‑time errors for invalid routes
  • Safer refactors
  • IntelliSense that suggests only valid paths

Route‑Aware Helpers

The App Router automatically generates global helpers (no imports required) during next dev, next build, or via next typegen.

Available helpers

  • PageProps – typed props for page components
  • LayoutProps – typed props for layout components
  • RouteContext – typed context for API routes

Using PageProps

// pages/details/[slotId]/page.tsx
export default function Details({
  params,
  searchParams,
}: {
  params: { slotId: string };
  searchParams: { name?: string };
}) {
  const { slotId } = params;
  const { name } = searchParams;

  return (
    <>
      Slot: {slotId}
      <br />
      Name: {name}
    </>
  );
}

A more concise, type‑safe version:

export default async function Details(
  props: PageProps
) {
  const { slotId } = await props.params;
  const { name } = await props.searchParams;

  return (
    <>
      Slot: {slotId}
      <br />
      Name: {name}
    </>
  );
}

Using LayoutProps

import type { ReactNode } from "react";

export default function RootLayout({
  children,
}: {
  children: ReactNode;
}) {
  return (
    <>
      {children}
    </>
  );
}

Typed version:

export default function RootLayout(
  props: LayoutProps
) {
  return (
    <>
      {props.children}
    </>
  );
}

Using RouteContext in API routes

import { NextRequest, NextResponse } from "next/server";

export async function GET(
  _request: NextRequest,
  ctx: RouteContext
) {
  const { id } = await ctx.params;

  return NextResponse.json({ msg: `Hello, ${id}!` });
}

RouteContext provides full IntelliSense for route parameters, eliminating manual typing.

Typed NextRequest and NextResponse

Both classes extend the standard Web APIs with Next‑specific helpers.

NextRequest

  • Typed cookies
  • Parsed URLs via nextUrl
  • Middleware‑friendly helpers

NextResponse

  • json() – send JSON responses
  • redirect() – perform redirects
  • Cookie helpers
  • Edge‑friendly APIs

Example:

import { NextRequest, NextResponse } from "next/server";

export async function GET(_request: NextRequest) {
  return NextResponse.json({ msg: "Hello!!!" });
}

Conclusion

Next.js type safety isn’t about writing more types; it’s about using TypeScript as a guardrail that reduces bugs without adding overhead. By enabling the built‑in TypeScript plugin, typed routes, and route‑aware helpers, you get compile‑time guarantees and richer editor support throughout your application.

Reference: Next.js – TypeScript documentation

Back to Blog

Related posts

Read more »