TypeScript with Next.js

Building type-safe React applications

🎨 What is TypeScript with Next.js?

Next.js has built-in TypeScript support, providing type safety for React components, API routes, and server-side rendering. It enhances development with autocomplete and catches errors early.


// Next.js page component with TypeScript
export default function Home() {
  return (
    <div>
      <h1>Welcome to Next.js with TypeScript!</h1>
    </div>
  )
}
                                    

Key Features

⚛️

Typed Components

Type-safe React components

interface Props {
  title: string
}
🛣️

API Routes

Type-safe API endpoints

export default function 
handler(req, res) {
  res.json({})
}
📄

Page Props

Typed getServerSideProps

export const 
getServerSideProps = 
async () => {
  return { props: {} }
}
🔄

Data Fetching

Type-safe data fetching methods

const data: User[] = 
await fetch('/api')
  .then(r => r.json())

🔹 Basic Next.js Page with TypeScript

Create a simple page component with typed props:

// pages/index.tsx
import { NextPage } from 'next'

interface HomeProps {
  title: string
  description: string
}

const Home: NextPage<HomeProps> = ({ title, description }) => {
  return (
    <div>
      <h1>{title}</h1>
      <p>{description}</p>
    </div>
  )
}

export default Home

Output:

Welcome to Next.js

Build fast, modern web applications

🔹 Typed API Routes

Create type-safe API endpoints in Next.js:

// pages/api/users.ts
import type { NextApiRequest, NextApiResponse } from 'next'

interface User {
  id: number
  name: string
  email: string
}

type ResponseData = {
  users: User[]
}

export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<ResponseData>
) {
  const users: User[] = [
    { id: 1, name: 'John Doe', email: '[email protected]' },
    { id: 2, name: 'Jane Smith', email: '[email protected]' }
  ]
  
  res.status(200).json({ users })
}

🔹 getServerSideProps with Types

Fetch data on the server with type safety:

// pages/users.tsx
import { GetServerSideProps, NextPage } from 'next'

interface User {
  id: number
  name: string
}

interface UsersPageProps {
  users: User[]
}

const UsersPage: NextPage<UsersPageProps> = ({ users }) => {
  return (
    <div>
      <h1>Users</h1>
      <ul>
        {users.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  )
}

export const getServerSideProps: GetServerSideProps<UsersPageProps> = async () => {
  const users: User[] = [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' }
  ]
  
  return {
    props: { users }
  }
}

export default UsersPage

🔹 Typed React Hooks

Use React hooks with TypeScript in Next.js:

import { useState, useEffect } from 'react'

interface Post {
  id: number
  title: string
  body: string
}

export default function Posts() {
  const [posts, setPosts] = useState<Post[]>([])
  const [loading, setLoading] = useState<boolean>(true)
  
  useEffect(() => {
    fetch('/api/posts')
      .then(res => res.json())
      .then((data: Post[]) => {
        setPosts(data)
        setLoading(false)
      })
  }, [])
  
  if (loading) return <p>Loading...</p>
  
  return (
    <div>
      {posts.map(post => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.body}</p>
        </article>
      ))}
    </div>
  )
}

🔹 App Router with TypeScript

Use the new App Router with TypeScript (Next.js 13+):

// app/page.tsx
interface PageProps {
  params: { id: string }
  searchParams: { [key: string]: string | string[] | undefined }
}

export default async function Page({ params, searchParams }: PageProps) {
  return (
    <div>
      <h1>App Router Page</h1>
      <p>Params: {params.id}</p>
    </div>
  )
}

// app/layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

🧠 Test Your Knowledge

What is the correct type for Next.js page component?