TypeScript 集成教程

学习如何在 Next.js 15 项目中有效使用 TypeScript,提升代码质量和开发体验

为什么选择 TypeScript?

TypeScript 为 JavaScript 添加了静态类型系统,帮助开发者在编译时发现错误, 提供更好的代码智能提示和重构支持。在 Next.js 15 中,TypeScript 支持是开箱即用的。

类型安全

编译时检查,减少运行时错误

开发体验

智能提示、自动补全、重构支持

代码质量

更好的代码可读性和维护性

基本类型系统

TypeScript 提供了丰富的类型系统,包括基本类型、联合类型、接口等。 这些类型帮助我们更好地描述数据的结构和函数的行为。

基本类型示例
// 基本类型定义
let count: number = 0;
let message: string = "Hello TypeScript";
let isActive: boolean = true;
let items: string[] = ["apple", "banana", "orange"];
let user: { id: number; name: string } = { id: 1, name: "张三" };

// 联合类型
let status: "loading" | "success" | "error" = "loading";

// 函数类型
function greet(name: string): string {
  return `Hello, ${name}!`;
}

// 可选参数
function createUser(name: string, age?: number) {
  return { name, age: age || 0 };
}

接口和类型定义

接口(Interface)是 TypeScript 中定义对象类型的主要方式。 它们可以描述对象的形状、函数的签名、类的结构等。

接口定义示例
// 接口定义
interface User {
  id: number;
  name: string;
  email: string;
  isActive?: boolean; // 可选属性
  readonly createdAt: Date; // 只读属性
}

interface TodoItem {
  id: number;
  text: string;
  completed: boolean;
  tags?: string[];
}

// 继承接口
interface AdminUser extends User {
  permissions: string[];
  role: "admin" | "superadmin";
}

// 泛型接口
interface ApiResponse<T> {
  data: T;
  status: number;
  message: string;
}

// 使用示例
const userResponse: ApiResponse<User> = {
  data: { id: 1, name: "张三", email: "zhang@example.com", createdAt: new Date() },
  status: 200,
  message: "成功"
};

TypeScript 类型系统全览

深度探索 TypeScript 的类型系统,从基础类型到高级泛型

基础类型 演示

TypeScript 代码:
// 基础类型示例
let name: string = "张三";
let age: number = 25;
let isStudent: boolean = true;
let hobbies: string[] = ["读书", "编程"];
let score: number | null = null;

// 类型别名
type Status = "pending" | "success" | "error";
let currentStatus: Status = "pending";
类型检查结果:
点击"类型检查"按钮查看结果

TypeScript 配置优化

学习如何配置 tsconfig.json 来优化开发体验和类型检查

严格模式选项

启用所有严格类型检查
禁止隐式 any 类型
禁止隐式返回
检查未使用的局部变量
检查未使用的参数

生成的 tsconfig.json

{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false
  }
}

类型安全演示

体验 TypeScript 如何确保数据的类型安全和一致性

类型安全的用户对象

ID:1
姓名:张三
邮箱:zhangsan@example.com
状态:活跃

类型安全的待办事项

学习 TypeScript#1
构建 Next.js 应用#2

React 组件类型定义

学习如何为 React 组件定义严格的 Props 类型

类型安全的 Button 组件

类型约束演示

选择按钮类型(TypeScript 确保只能选择预定义的值):

当前选择: primary

Next.js 特定类型

Next.js 提供了许多内置类型来帮助开发者构建类型安全的应用程序。 这些类型涵盖了页面组件、API 路由、元数据等各个方面。

Next.js 类型定义
// Next.js 特定类型
import { NextRequest, NextResponse } from 'next/server';
import { Metadata } from 'next';

// 页面组件类型
interface PageProps {
  params: { id: string };
  searchParams: { [key: string]: string | string[] | undefined };
}

export default function ProductPage({ params, searchParams }: PageProps) {
  return <div>Product ID: {params.id}</div>;
}

// API 路由类型
export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url);
  const id = searchParams.get('id');

  return NextResponse.json({ id });
}

export async function POST(request: NextRequest) {
  const body = await request.json();
  // 处理 POST 请求
  return NextResponse.json({ success: true });
}

// 元数据类型
export const metadata: Metadata = {
  title: '产品页面',
  description: '产品详情页面',
};

// 布局组件类型
interface LayoutProps {
  children: React.ReactNode;
  params: { locale: string };
}

export default function Layout({ children, params }: LayoutProps) {
  return <div lang={params.locale}>{children}</div>;
}

TypeScript 实用类型

TypeScript 提供了许多实用类型(Utility Types), 帮助我们基于现有类型创建新类型,提高代码的复用性和灵活性。

TypeScript 实用类型
// TypeScript 实用类型
interface User {
  id: number;
  name: string;
  email: string;
  password: string;
  isActive: boolean;
}

// Pick - 选择特定属性
type UserProfile = Pick<User, 'id' | 'name' | 'email'>;

// Omit - 排除特定属性
type CreateUserInput = Omit<User, 'id'>;

// Partial - 所有属性变为可选
type UpdateUserInput = Partial<User>;

// Required - 所有属性变为必需
type RequiredUser = Required<User>;

// Record - 创建对象类型
type UserRoles = Record<string, 'admin' | 'user' | 'guest'>;

// 条件类型
type NonNullable<T> = T extends null | undefined ? never : T;

// 映射类型
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

// 模板字面量类型
type EventName = `on${Capitalize<string>}`;
type ButtonEvent = `button${Capitalize<string>}`;

在线 TypeScript 编辑器

尝试编写 TypeScript 代码,体验类型检查和智能提示:

TypeScript 练习场

加载编辑器中...

TypeScript 最佳实践

推荐做法

  • 优先使用接口而不是类型别名定义对象结构
  • 为所有函数参数和返回值添加类型注解
  • 使用严格的 TypeScript 配置(strict: true)
  • 利用类型推断,避免不必要的类型注解

避免的做法

  • 过度使用 any 类型,失去类型安全性
  • 忽略 TypeScript 编译错误
  • 创建过于复杂的类型定义
  • 在不必要的地方显式声明类型

准备好了吗?

现在你已经掌握了 TypeScript 的核心概念,让我们继续学习 Prisma ORM 和数据库操作。

学习 Prisma ORM