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>
)
}