在實際的開發中,我們可能有如下場景:
- 有一個Student介面,用於與介面的返回型別相對應。
- 在一個StudentService,該方法中有一個update方法,用於更新Student.
情景回顧
Student:
interface Student {
id: number;
// 學號
no: number;
// 姓名
name: string;
// 手機號
phone: string;
// 性別
sex: boolean;
}
現在邏輯是這樣,在更新學生的資訊時,我們僅允許使用者更新name以及phone欄位。此時我們想在StudentService.update方法中體現僅僅允許更新這兩個欄位,我們有兩種寫法:
第一種,直接將引數型別宣告為Student:
class StudentService {
void update(id: number, student: Student) {
}
}
第二種,直接在引數中宣告欄位型別:
class StudentService {
void update(id: number, student: {name: string, phone: string}) {
}
}
弊端分析
第一種方法的弊端在於我們無法通過update
方法的宣告能直接得到該方法中更新學生的欄位,但其優勢在於可以快速的顯示Student實體的變更,比如在後期中我們將phone
欄位變更為mobile
。
第二種方法的優勢是可以在update
方法直接得出要更新的欄位,但弊端是無法快速的響應Student
實體在日後的欄位變更。
建議方案
其實我是想要一個類似於如下的引數宣告:
class StudentService {
void update(id: number, student: {name: string, phone: string} as Student) {
}
}
但很遺憾的是typescript
並不支援這種寫法,那麼退而求其次,我們可以這樣寫:
class StudentService {
void update(id: number, student: {name: string, phone: string}) {
student = student as Student;
}
}
簡單的在函式的第一行增加一個型別推導,這樣一來:
- 當
Student
型別發生變更時,我們可以通過語法檢查自動地發現該行程式碼發生了語法錯誤,進而進行修正。 - 由於在引數中我們直接宣告瞭各個欄位,而不是使用
Student
進行廣泛的宣告,我們可以直接獲取到該update
方法具體更新的功能。