Nestjs docs have no mention of mixin
, so this is what I gathered from google and stackoverflow:
- A mixin is a way to share code between classes in nest.
- It is a class that contains methods that can be used by other classes, and can be registered as a provider using the
@Injectable()
decorator. - Mixins are used to add additional functionality to a class without modifying the original class, and can be used with controllers, services, pipes, and guards.
- Examples often include classes inheriting from mixins:
class SomeClass extends MixinClass {}
At first I thought that this is for semantics sake, as inheritance implies a certain relationship between two classes, while a mixin is a way of sharing code. But the mechanics of using a mixin in nest are still relying on inheritance(extends
keyword).
What I am missing about mixins? How are they different from inheritance?
It seems that class SomeClass extends SomeOtherClassThatIsntAMixin {}
achieves the same results.
CodePudding user response:
One big thing you're missing about mixins is that they are functions that return a class reference that Nest can then instantiate. It would be like letting a class have a protected name: string
property that child classes could override, but instead of having to create a child class that extends the parent class, you can just use MixinClass('someNewName')
and the function should return a child class reference with the new name
property. The AuthGuard
and FileInterceptor
are two mixins that pass options to the new class without you having to create these new child classes.
Edit:
Something else I forgot to initially mention is that mixins allow you to hide the constructor of the class reference. This is useful if you have something that you always want injected, but want to allow user customization to come in with. In the AuthGuard
, we optionally inject the passport options set by the PassportModule.register()
method, and the strategy passed via AuthGuard('strategy')
does not interfere with those options. By using a closure we can avoid letting devs accidentally overwrite the constructor which could cause the class to fail, or cause Typescript to complain leading to a headache for the dev to deal with