網站搜尋

TypeScript - NestJS - mixins 的用途以及它們與繼承有何不同?


Nestjs 文件沒有提到 mixin,所以這是我從 Google 和 StackOverflow 收集到的資訊:

  • mixin 是在 Nest 中在類別之間共享程式碼的一種方式。
  • 這是一個包含可被其他類別使用的方法的類別,並且可以使用 @Injectable() 裝飾器註冊為提供者。
  • Mixins 用於在不修改原始類別的情況下向類別添加額外功能,並且可以與控制器、服務、管道和守衛一起使用。
  • 範例通常包括從 mixin 繼承的類別:class SomeClass extends MixinClass {}

一開始我以為這只是語義上的區別,因為繼承意味著兩個類之間存在某種關係,而 mixin 是一種共享代碼的方式。但在 nest 中使用 mixin 的機制仍然依賴於繼承(extends 關鍵字)。

我對混入(mixins)不了解的地方是什麼?它們與繼承有何不同?
看起來 class SomeClass extends SomeOtherClassThatIsntAMixin {} 可以達到相同的效果。

答案#1

關於 mixins,你遺漏的一個大點是,它們是 函數,會返回一個類別參考,然後 Nest 可以實例化它。這就像是讓一個類別有一個 protected name: string 屬性,子類可以覆寫,但你不必創建一個繼承父類的子類,你只需要使用 MixinClass('someNewName'),這個函數 應該 返回一個帶有新 name 屬性的子類參考。AuthGuard 和 FileInterceptor 是兩個 mixins,它們將選項傳遞給新類,而你無需創建這些新的子類。

編輯:

我最初忘記提到的另一件事是,混入類別(mixins)允許你隱藏類別引用的建構函式。這在你有一些總是想要注入的東西,但又希望允許使用者自訂時非常有用。在 AuthGuard 中,我們可以選擇性地注入由 PassportModule.register() 方法設置的 Passport 選項,並且透過 AuthGuard('strategy') 傳入的策略不會干擾那些選項。透過使用閉包,我們可以避免開發者不小心覆寫建構函式,這可能導致類別失敗,或讓 Typescript 拋出錯誤,讓開發者頭痛不已。