TypeScript trong React
React component nhận props — nhưng JS không biết props có field gì. TypeScript bắt buộc khai báo kiểu props, nên editor sẽ gạch đỏ ngay nếu bạn truyền sai hoặc thiếu.
// File: UserCard.tsx
// Khai báo kiểu props
interface UserCardProps {
name: string
email: string
role: "admin" | "student" | "teacher"
avatar?: string // optional
}
// Component nhận props có kiểu rõ ràng
function UserCard({ name, email, role, avatar }: UserCardProps) {
return (
<div className="user-card">
{avatar && <img src={avatar} alt={name} />}
<h3>{name}</h3>
<p>{email}</p>
<span className={`badge badge-${role}`}>{role}</span>
</div>
)
}
// Dùng component — editor tự gợi ý props
<UserCard name="An" email="an@mail.com" role="student" />
// <UserCard name="An" /> ← 🔴 Error: thiếu email và role
TypeScript trong Node.js/Express
// File: routes.ts
import { Request, Response } from 'express'
import { z } from 'zod'
// Zod schema = validation + type generation
const CreateUserSchema = z.object({
name: z.string().min(2, 'Tên tối thiểu 2 ký tự'),
email: z.string().email('Email không hợp lệ'),
password: z.string().min(8, 'Mật khẩu tối thiểu 8 ký tự'),
})
// Tự động tạo TypeScript type từ Zod schema
type CreateUserInput = z.infer<typeof CreateUserSchema>
// = { name: string; email: string; password: string }
async function createUser(req: Request, res: Response) {
// Validate + parse: nếu sai format tự throw error
const data = CreateUserSchema.parse(req.body)
// data đã được TypeScript biết có .name, .email, .password
const user = await db.users.create({
name: data.name,
email: data.email,
passwordHash: await hash(data.password),
})
res.status(201).json({ user })
}
Generics: viết hàm dùng lại cho nhiều kiểu
// File: generics.ts
// Không generic: phải viết hàm riêng cho mỗi kiểu
function firstNumber(arr: number[]): number | undefined {
return arr[0]
}
function firstString(arr: string[]): string | undefined {
return arr[0]
}
// Có generic: 1 hàm dùng cho TẤT CẢ kiểu
function first<T>(arr: T[]): T | undefined {
return arr[0]
}
first<number>([1, 2, 3]) // number | undefined
first<string>(["a", "b"]) // string | undefined
first([true, false]) // TypeScript tự suy luận: boolean
// Ứng dụng thực tế: API response wrapper
interface ApiResponse<T> {
success: boolean
data: T
error?: string
}
// Dùng cho user
const userRes: ApiResponse<User> = {
success: true,
data: { id: 1, name: "An", email: "an@mail.com" },
}
💡 Zod = validation + types
Viết schema Zod một lần, dùng z.infer để tạo TypeScript type tự động. Không phải viết type và validation riêng — DRY (Don’t Repeat Yourself). Đây là pattern chuẩn trong production.
❓ z.infer<typeof schema> làm gì?
- Viết React component với typed props (interface)
- Dùng Zod + z.infer để tạo type từ schema
- Hiểu generic cơ bản với <T>
- Type Express Request/Response