在 Day 07 認識 Props 時,知道外層 Component 可以將資料或函式傳給內層 Component:
<TodoItem
todo={todo}
onToggle={onToggle}
onDelete={onDelete}
/>
不過當專案加入 TypeScript 後,除了要知道「傳了哪些 Props」,還要描述每個 Prop 應該接收什麼型別。
目前 TodoItem.tsx 使用 interface 描述 Props:
interface TodoItemProps {
todo: Todo
onToggle: (id: number) => void
onDelete: (id: number) => void
}
這份 TodoItemProps 可以理解成 TodoItem 的資料使用說明。
定義好 TodoItemProps 後,會將它寫在 Component 的參數旁邊:
function TodoItem({
todo,
onToggle,
onDelete,
}: TodoItemProps) {
// ...
}
這是在告訴 TypeScript,解構出來的 todo、onToggle 和 onDelete,都要符合 TodoItemProps 的規定。
所以 TypeScript 會知道 todo 是一筆 Todo,而 onToggle 和 onDelete 都是接收數字的函式。有了這層資訊,編輯器在輸入 todo. 時,也能根據 Todo 型別提示 id、text、completed 等屬性。
TodoItemProps 中的三個欄位目前都是必填。如果使用 TodoItem 時漏掉 onDelete:
<TodoItem
todo={todo}
onToggle={onToggle}
/>
TypeScript 會提醒缺少必要的 onDelete。
這樣在程式執行前,就能先發現 Component 收到的資料不完整,不用等到按下刪除按鈕後,才發現沒有函式可以呼叫。
todo 這個 Prop 必須符合 Todo 的格式,也就是包含 id、text、completed 三個屬性。
如果將普通字串傳給 todo:
<TodoItem
todo="學習 TypeScript"
onToggle={onToggle}
onDelete={onDelete}
/>
TypeScript 就會提醒 string 不符合 Todo 型別。
可見 Props 型別不只會檢查有沒有傳入資料,也會檢查傳入的資料是否符合預期。
Props 不一定只是文字或物件,也可以是一個函式。
目前的 onDelete 型別是:
(id: number) => void
這表示它需要接收一個 number,呼叫後不需要使用它的回傳結果。
所以在 TodoItem 中可以這樣使用:
onClick={() => onDelete(todo.id)}
因為 todo.id 是 number,符合 onDelete 的規定。
但如果改成傳入字串:
onDelete('1')
TypeScript 就會提出型別錯誤。這讓外層傳入函式後,內層 Component 也能知道應該用什麼資料呼叫它。
type 和 interface 都可以描述 Props目前專案選擇使用 interface 描述 TodoItemProps,也可以改用前面認識的 type 達到相同效果。
對這種簡單的 Props 來說,兩者都能完成型別檢查。React 沒有規定一定要選哪一個,依照專案原本的寫法即可。
React 官方文件:在 React 中使用 TypeScript
Props 的型別主要在開發階段由 TypeScript 檢查,可以幫忙發現:
但 TypeScript 的型別在轉換成 JavaScript 後會被移除,所以它不會在瀏覽器執行時自動檢查外部資料。
如果資料來自 API 或使用者輸入,仍然不能只因為寫了型別,就認為收到的內容一定正確。
interface 或 type 描述以前只要知道 Props 是怎麼從外層傳進來,現在還要替它們寫上型別,看起來好像多了一道手續。但同時也讓 Component 更清楚地說明自己需要哪些資料,傳錯或少傳時也能提早被發現。
到目前為止,算是先認識了 TypeScript 中幾個常見的基礎寫法。雖然距離真正摸熟它還有一大段路要走,但至少之後再看到型別時,應該不會像一開始那麼陌生。
從下一篇開始就不再只是單純閱讀程式碼,而是準備使用 React + TypeScript 從頭建立另一個專案。我預計會把想做的功能與需求交給 AI,觀察它會如何規劃與生成程式碼,再一邊運用目前學過的概念,理解每個部分在做什麼、思考哪些地方可以調整,而不是拿到程式碼後就直接照單全收。
總之就是接下來正式從 React 與 TypeScript 的基礎學習,進入 AI 協作的階段。
下篇見:)