DEV Community

Discussion on: How can I reduce amount of boilerplate code while working with TypeScript+mongoose 🙈

Collapse
 
nuclight profile image
Konstantin Alikhanov

Ok, this is good one. Thank you.
How can I optimize other fields?

Collapse
 
nickytonline profile image
Nick Taylor

I'm on mobile at the moment. I'll post some other suggestions in a bit when I'm back at my laptop. On general though, union types and generics really help with these kinds of situations to make types more maintainable.

Thread Thread
 
nickytonline profile image
Nick Taylor • Edited

From there you could even do a Mongoose document generic type.

type Entity<T> = T & {
    id: string;
    createdAt: Date;
}

interface Vehicle {
    model: string;
    year?: string;
    seatsCount?: number;
}

type MongooseDocument<T> = T & mongoose.Document

const dbDocument: MongooseDocument<Entity<Vehicle>> = {
    SomeMongooseDocProperty: 'yolo',
    createdAt: new Date(),
    id: '5FCA1C32-1D92-47CA-A885-A5A747E6E4FB',
    model: 'Mini',
    seatsCount: 4,
    year: '1999'
}

You could refine this more if you wanted to make a Vehicle type which just wraps the Entity<T>.

You can see it in action in the enhanced TypeScript playground.

Also, this might interest you.

Thread Thread
 
nuclight profile image
Konstantin Alikhanov

Ok, I will play with it. Thank you.

Thread Thread
 
nickytonline profile image
Nick Taylor

You can even go a bit further.

interface BaseEntity {
  id: string;
  createdAt: Date;
}

type Entity<T> = T & BaseEntity;

interface Vehicle {
  model: string;
  year?: string;
  seatsCount?: number;
}

// Enforce having the bare minimum entity properties
type MongooseDocument<T extends BaseEntity> = T & mongoose.Document;

const dbDocument: MongooseDocument<Entity<Vehicle>> = {
  SomeMongooseDocProperty: "yolo",
  createdAt: new Date(),
  id: "5FCA1C32-1D92-47CA-A885-A5A747E6E4FB",
  model: "Mini",
  seatsCount: 4,
  year: "1999"
};

See the updated playground example