在前端開發中,一種規劃引數型別的新思路

myskies發表於2022-02-19

在實際的開發中,我們可能有如下場景:

  1. 有一個Student介面,用於與介面的返回型別相對應。
  2. 在一個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;
  }
}

簡單的在函式的第一行增加一個型別推導,這樣一來:

  1. Student型別發生變更時,我們可以通過語法檢查自動地發現該行程式碼發生了語法錯誤,進而進行修正。
  2. 由於在引數中我們直接宣告瞭各個欄位,而不是使用Student進行廣泛的宣告,我們可以直接獲取到該update方法具體更新的功能。

相關文章