با React (with React)
در «تایپ اسکریپت با ری اکت» خطاها زود دیده می شوند. چون تایپ ایستا یعنی بررسی نوع ها هنگام کامپایل است. بنابراین تغییر کدها امن تر می شود و تکمیل خودکار دقیق تر است.
چرا TypeScript کنار React؟
تایپ برای پراپس ها، state و context نظم می آورد. سپس خطاها زودتر پیدا می شوند و بازآرایی ساده تر می شود. مثل دفتر مشق مرتب در مدرسه.
شروع سریع با Vite
یک برنامه تازه بساز. سپس وابستگی ها را نصب کن و اجرا کن.
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run dev
پیکربندی tsconfig برای React
گزینه ها را مانند نمونه تنظیم کن. سپس حالت strict را روشن نگه دار.
{
"compilerOptions": {
"target": "ES2020",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "Node",
"jsx": "react-jsx",
"strict": true,
"skipLibCheck": true,
"noEmit": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src"]
}
تایپ کردن کامپوننت ها
برای پراپس ها نوع بساز. سپس در تابع استفاده کن.
type GreetingProps = {
name: string;
age?: number;
};
export function Greeting({ name, age }: GreetingProps) {
return (
<div>
<h2>Hello, {name}!</h2>
{age !== undefined && <p>You are {age} years old</p>}
</div>
);
}
الگوهای رایج در ری اکت تایپ شده
رویدادها به صورت Type-Safe
هندلر ورودی و دکمه را دقیق تایپ کن.
function NameInput() {
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
console.log(e.target.value);
}
return <input onChange={handleChange} />;
}
function SaveButton() {
function handleClick(e: React.MouseEvent<HTMLButtonElement>) {
e.preventDefault();
}
return <button onClick={handleClick}>Save</button>;
}
useState با نوع های دقیق
برای اعداد، یونین ها و مقدار تهی نوع بده.
const [count, setCount] = React.useState<number>(0);
const [status, setStatus] = React.useState<'idle' | 'loading' | 'error'>('idle');
type User = { id: string; name: string };
const [user, setUser] = React.useState<User | null>(null);
useRef برای DOM
رف را به نوع عنصر DOM گره بزن.
function FocusInput() {
const inputRef = React.useRef<HTMLInputElement>(null);
return <input ref={inputRef} onFocus={() => inputRef.current?.select()} />;
}
تایپ children
از React.ReactNode برای فرزندها استفاده کن.
type CardProps = { title: string; children?: React.ReactNode };
function Card({ title, children }: CardProps) {
return (
<div>
<h2>{title}</h2>
{children}
</div>
);
}
ژنریک ها برای درخواست ها
پاسخ API را با ژنریک ها تایپ کن.
async function fetchJson<T>(url: string): Promise<T> {
const res = await fetch(url);
if (!res.ok) {
throw new Error('Network error');
}
return res.json() as Promise<T>;
}
async function loadPosts() {
type Post = { id: number; title: string };
const posts = await fetchJson<Post[]>('/api/posts');
console.log(posts);
}
کانتکست کوچک و هوک سفارشی
کانتکست تایپ شده بساز. سپس هوک کمکی تعریف کن.
type Theme = 'light' | 'dark';
const ThemeContext = React.createContext<{ theme: Theme; toggle(): void } | null>(null);
function ThemeProvider({ children }: { children: React.ReactNode }) {
const [theme, setTheme] = React.useState<Theme>('light');
const value = { theme: theme, toggle: () => setTheme((t) => (t === 'light' ? 'dark' : 'light')) };
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
}
function useTheme() {
const ctx = React.useContext(ThemeContext);
if (!ctx) {
throw new Error('useTheme must be used within ThemeProvider');
}
return ctx;
}
نکته: فایل src/vite-env.d.ts بساز و تایپ های ویت را اضافه کن. یا کلید types را در tsconfig.json تنظیم کن.
/// <reference types="vite/client" />
{
"compilerOptions": {
"types": ["vite/client"]
}
}
هشدار: از React.FC الزامی نیست. تابع ها را مستقیم تایپ کن. سپس اگر لازم بود children را دستی اضافه کن.
جمع بندی سریع
- فوکوس: تایپ اسکریپت با ری اکت امن تر است.
- پراپس، state و رویدادها را دقیق تایپ کن.
- گزینه
strictرا همیشه روشن بگذار. - ژنریک ها پاسخ API را ایمن می کنند.
ادامه مسیر: بخش با Node.js و صفحه پیکربندی را ببین. همچنین خود تایپ اسکریپت با ری اکت را نشانه گذاری کن.