Understanding NestJS Mixins and Their Distinction from Inheritance

After researching, I found that the Nestjs documentation does not include any information about mixins. Here is what I have gathered from my findings on Google and Stack Overflow:

  • A mixin serves as a means of code sharing between classes within Nest.
  • Essentially, it is a class that contains methods that can be utilized by other classes, and can be declared as a provider with the @Injectable() decorator.
  • Mixins enable the addition of extra functionalities to a class without altering the original class itself, and can be applied to controllers, services, pipes, and guards.
  • Commonly, examples involve classes inheriting traits from mixins:
    class SomeClass extends MixinClass {}

Initially, it appeared to me that this distinction was merely semantic, since inheritance implies a specific relationship between two classes, whereas a mixin is focused on code sharing. However, in practice, using a mixin in Nest seems to still rely on inheritance (utilizing the extends keyword).

My question now is: What exactly sets mixins apart? How do they differentiate from inheritance?
It appears that utilizing

class SomeClass extends SomeOtherClassThatIsntAMixin {}
yields comparable outcomes.

Answer №1

Another interesting aspect of mixins is that they act as functions that return a class reference for Nest to instantiate. It's similar to giving a class a protected name: string property that child classes can override, but instead of creating a new child class, you can simply use MixinClass('someNewName'). The function should then return a child class reference with the updated name property. Two examples of mixins are AuthGuard and FileInterceptor, which allow passing options to the new class without the need to create separate child classes.

Additionally, I overlooked mentioning another key benefit of mixins - they enable hiding the constructor of the class reference. This becomes handy when there's a constant injection required but customization is also desired. In the case of AuthGuard, we can inject passport options set by PassportModule.register(), while the strategy specified via AuthGuard('strategy') does not interfere with these settings. Using a closure helps prevent accidental overwriting of the constructor, potentially causing class failures or Typescript errors that would perplex developers.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"How to incorporate SortableJS into Ionic 3 Angular app with the help of the systemjs.config.js

I'm currently following the instructions on https://github.com/SortableJS/angular-sortablejs and I seem to be facing an issue with the systemjs.config.js file. My app is built using Ionic 3 and Angular 4. To address this, I created a script called sy ...

Determining the function return type by analyzing an array of functions

If you have a vanilla JavaScript function that accepts an array of callbacks (each returning an object) and combines their outputs, how can TypeScript be used to determine the return type of this function? While ReturnType is typically used for a single ...

Tips for retrieving the generated ID from the server immediately following form submission using the Post method in TypeScript

When submitting a long-form, it is important to ensure that no data is lost. Users should be able to stay on the same page to make any necessary changes after clicking the submit button. I need to receive the unique id generated by the server upon submissi ...

Retrieve the data in JSON format including the child elements from a PostgreSQL

I have data from a table in Postgres that I need to be returned in Json format with its children properly ordered. So far, I haven't found a solution to achieve this. Is there a way in PostgreSQL to order the parent modules along with their child modu ...

How can we implement type guarding for a generic class in TypeScript?

Implementing a generic class in TypeScript that can return different types based on its constructor parameter. type Type = 'foo' | 'bar'; interface Res { 'foo': {foo: number}; 'bar': {bar: string}; } class ...

What is the correct way to declare a class as global in TypeScript?

To prevent duplication of the class interface in the global scope, I aim to find a solution that avoids redundancy. The following code snippet is not functioning as intended: lib.ts export {} declare global { var A: TA } type TA = typeof A class A { ...

retrieving a single object from $resource by passing a non-ID parameter

I am utilizing $resource to retrieve an array of objects. The method I am invoking is as follows: fetchTeamResource(): ng.resource.IResourceClass<ITeamResource> { return this.$resource("/api/Teams:teamId"); } Below is how I am i ...

Having trouble locating the namespace for angular in typescript version 1.5

I am using Angular 1.5 with TypeScript and have all the necessary configurations in my tsconfig.json file. However, when I run tslint, I encounter numerous errors in the project, one of which is: Cannot find namespace angular My tsconfig.json file looks ...

Encountering an error while compiling the Angular 8 app: "expected ':' but got error TS1005"

As I work on developing an Angular 8 application through a tutorial, I find myself facing a challenge in my header component. Specifically, I am looking to display the email address of the currently logged-in user within this component. The code snippet fr ...

How can I prevent Intellisense from automatically importing all global variables from Mocha (or any other testing library) into files that are not designated for testing purposes?

I am managing these files in the same directory. package.json: { "name": "example", "version": "1.0.0", "devDependencies": { "@types/mocha": "^7.0.1", "@types/node": "^13.7.1" } } tsconfig.json: {} index.ts: export const test = () =&g ...

What is the reason for `downlevelIteration` not being enabled by default?

When directing towards ES5 and using the spread operator ... to convert an Iterator to an Array, it prompts the need for the -downlevelIteration compiler option. Enabling this option allows the spread operators to function without any errors. I'm cur ...

Lambda functions that support multiple languages coexisting in a single directory

As I have lambda functions written in both Typescript and Java, I am contemplating whether to store them all together in a single directory or separate them based on the language. Our infrastructure deployment is done using terraform and CI/CD with Jenki ...

The type Observable<any> cannot be assigned to Observable<any> type

I am currently working with angular 5 and ionic 3. I have defined an interface: export interface IAny { getDataSource: Observable<any>; } Components that implement this interface must have the following method: getDataSource () { return ...

how to send both the useState setter and object as props to a child component in React using TypeScript

Having an issue with passing useState setter and object (both together) to the child component. Successfully passed the object by spreading it like this {...object}, but unsure of the syntax to pass the setter along as well. Here's a code example: < ...

Failed to decipher an ID token from firebase

I'm feeling extremely frustrated and in need of assistance. My goal is to authenticate a user using Google authentication so they can log in or sign up. Everything worked perfectly during development on localhost, but once I hosted my app, it stopped ...

Submitting the form leads to an empty dynamically added row

I am currently working on a gender overview that allows you to edit, add, or delete genders using a simple table. The functionality of adding and deleting rows is already implemented. However, I am facing issues with displaying the correct web API data as ...

Issue with applying value changes in Timeout on Angular Material components

I'm currently experimenting with Angular, and I seem to be struggling with displaying a fake progress bar using the "angular/material/progress-bar" component. (https://material.angular.io/components/progress-bar/) In my "app.component.html", I have m ...

Exploring Angular data iteration with Tab and its contentLearn how to loop through Tab elements

Upon receiving a response from the API, this is what I get: const myObj = [ { 'tabName': 'Tab1', 'otherDetails': [ { 'formType': 'Continuous' }, { 'formType& ...

Disabling `no-dupe-keys` in ESLint does not seem to be effective

Currently, I am working on a project where I have incorporated Typescript and ESLint. However, I have encountered an issue with the error message stating: An object literal cannot have multiple properties with the same name. I am looking to disable this s ...

What could be causing the Uncaught Error to persist even after using .catch()?

Check out this code snippet: function pause(ms:number) { return new Promise((resolve:any,reject:any) => setTimeout(resolve,ms)) } async function throwError(): Promise<void> { await pause(2000) console.log("error throw") throw new ...