技術 5 分鐘閱讀
React + TypeScript 開發心得:型別安全的真正價值
前言
最近把手邊的幾個 React 專案都升級成 TypeScript 了。一開始覺得多寫型別很麻煩,但用了幾個月後,我已經無法想像不用 TypeScript 的日子。
為什麼要用 TypeScript?
編譯時就抓到錯誤
沒有 TypeScript 的時候,很多 bug 要到瀏覽器跑起來才會發現。TypeScript 把錯誤提前到編輯器裡:
// ❌ TypeScript 會直接報錯
interface Product {
id: number;
name: string;
price: number;
}
function formatPrice(product: Product) {
return product.prce; // 拼錯了!TS 會提示
}
IDE 自動補全
定義好型別後,VS Code 的自動補全變得超級精準,開發速度反而更快了。
React 常用型別模式
Props 定義
interface ButtonProps {
label: string;
variant?: 'primary' | 'secondary' | 'danger';
disabled?: boolean;
onClick: () => void;
}
function Button({ label, variant = 'primary', disabled, onClick }: ButtonProps) {
return (
<button
className={`btn btn-${variant}`}
disabled={disabled}
onClick={onClick}
>
{label}
</button>
);
}
useState 型別
interface User {
id: number;
name: string;
email: string;
}
const [user, setUser] = useState<User | null>(null);
const [items, setItems] = useState<Product[]>([]);
Event Handler 型別
function SearchBar() {
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
console.log(e.target.value);
};
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
};
return (
<form onSubmit={handleSubmit}>
<input onChange={handleChange} />
</form>
);
}
API 回應型別
interface ApiResponse<T> {
data: T;
meta: {
current_page: number;
last_page: number;
total: number;
};
}
async function fetchProducts(): Promise<ApiResponse<Product[]>> {
const response = await fetch('/api/products');
return response.json();
}
與 Laravel 搭配的型別同步
搭配 Inertia.js 使用時,可以用套件自動從 Laravel 產生 TypeScript 型別:
npm install -D @tightenco/ziggy
也可以手動維護一個 types.d.ts:
// resources/js/types.d.ts
export interface PageProps {
auth: {
user: User | null;
};
flash: {
message?: string;
};
}
常見的 TypeScript 地雷
不要濫用 any
// ❌ 不好
const data: any = fetchData();
// ✅ 正確
const data: Product[] = await fetchProducts();
善用 Utility Types
// 讓所有欄位變成 optional
type ProductFormData = Partial<Product>;
// 只挑選需要的欄位
type ProductPreview = Pick<Product, 'name' | 'price'>;
// 排除某些欄位
type CreateProduct = Omit<Product, 'id' | 'created_at'>;
搭配好用的工具
推薦在 VS Code 安裝以下外掛加強 TypeScript 體驗:
- Pretty TypeScript Errors:讓錯誤訊息更易讀
- TypeScript Importer:自動匯入型別
小結
目前覺得 TypeScript 前期投入的學習成本,在中長期絕對值回票價。特別是接案的場景,型別安全能大幅降低交付後的 bug 數量,讓客戶對你更有信心。
如果你需要類似的系統,歡迎聯繫討論。
#React #TypeScript