You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
dependabot[bot] b6ddec4873
chore(deps): bump JamesIves/github-pages-deploy-action (#837)
7 days ago
.github chore(deps): bump JamesIves/github-pages-deploy-action (#837) 7 days ago
.husky chore(husky): upgrade to version "6.0.0" 2 years ago
.vscode chore(vscode/tasks): disable auto-run of tasks 10 months ago
docs dependencies(mongoose): upgrade to 7.2.0 2 weeks ago
src dependencies(mongoose): upgrade to 7.2.0 2 weeks ago
test Merge remote-tracking branch 'origin/master' into beta 4 weeks ago
website chore(website/yarn.lock): lockfile maintenance 2 weeks ago
.editorconfig enable "strictNullChecks" 3 years ago
.eslintignore style: fix some typos (#754) 9 months ago
.eslintrc.js style: fix some typos (#754) 9 months ago
.gitignore Add Inheritance Tests 4 years ago
.npmignore Small Changes 4 years ago
.npmrc Set Version to 6.0.0-0 [Pre] 4 years ago
.prettierrc chore: replace "tslint" with "eslint" 2 years ago
.releaserc.js style: fix some typos (#754) 9 months ago
CHANGELOG.md release: v11.2.0 2 weeks ago
LICENSE chore(LICENSE): update for 2022 10 months ago
README.md docs(README): update typegoose 11 release date 2 months ago
commitlint.config.js style: apply eslint rules to top level and website js files 2 years ago
ghPagesPre.sh chore(ghPagesPre): fix script (exit on error) 2 years ago
jest.config.json dependencies(jest): upgrade to 29.0.3 6 months ago
jest.config.tsd.json chore: add tsd-lite as jest tests 11 months ago
lint-staged.config.js style: apply eslint rules to top level and website js files 2 years ago
package.json release: v11.2.0 2 weeks ago
tsconfig.build.json style: apply eslint rules to top level and website js files 2 years ago
tsconfig.buildTests.json chore: exclude ".test-d.ts" files from "build:tests" script 6 months ago
tsconfig.json feat(tsconfig.json): update "target" to match minimal NodeJS capabilities 6 months ago
yarn.lock dependencies(mongoose): upgrade to 7.2.0 2 weeks ago

README.md

Typegoose

(These badges are from typegoose:master)
Node.js Tests codecov.io npm

Define Mongoose models using TypeScript classes

Migration

Migration Guides:
(Date format: dd-mm-yyyy)

  • 10 to 11 (released on 27-03-2023)
  • 9 to 10 (released on 12-12-2022)
  • 8 to 9 (released on 22-09-2021)
  • 7 to 8 (released on 28-07-2021)
  • 6 to 7 (released on 01-04-2020)
  • 5 to 6 (released on 30-09-2019)

Basic usage

import { prop, getModelForClass } from '@typegoose/typegoose';
import * as mongoose from 'mongoose';

class User {
  @prop()
  public name?: string;

  @prop({ type: () => [String] })
  public jobs?: string[];
}

const UserModel = getModelForClass(User); // UserModel is a regular Mongoose Model with correct types

(async () => {
  await mongoose.connect('mongodb://localhost:27017/', { dbName: 'test' });

  const { _id: id } = await UserModel.create({ name: 'JohnDoe', jobs: ['Cleaner'] });
  const user = await UserModel.findById(id).exec();

  console.log(user); // prints { _id: 59218f686409d670a97e53e0, name: 'JohnDoe', __v: 0 }
})();

Motivation

A common problem when using Mongoose with TypeScript is that you have to define both the Mongoose model and the TypeScript interface. If the model changes, you also have to keep the TypeScript interface file in sync or the TypeScript interface would not represent the real data structure of the model.

Typegoose aims to solve this problem by defining only a TypeScript interface (class), which needs to be enhanced with special Typegoose decorators (like @prop).

Under the hood it uses the Reflect & reflect-metadata API to retrieve the types of the properties, so redundancy can be significantly reduced.

Instead of writing this:

// This is a representation of how typegoose's compile output would look like
interface Car {
  model?: string;
}

interface Job {
  title?: string;
  position?: string;
}

interface User {
  name?: string;
  age!: number;
  preferences?: string[];
  mainJob?: Job;
  jobs?: Job[];
  mainCar?: Car | string;
  cars?: (Car | string)[];
}

const JobSchema = new mongoose.Schema({
  title: String;
  position: String;
});

const CarModel = mongoose.model('Car', {
  model: string,
});

const UserModel = mongoose.model('User', {
  name: { type: String },
  age: { type: Number, required: true },
  preferences: [{ type: String }],
  mainJob: { type: JobSchema },
  jobs: [{ type: JobSchema }],
  mainCar: { type: Schema.Types.ObjectId, ref: 'Car' },
  cars: [{ type: Schema.Types.ObjectId, ref: 'Car' }],
});

You can just write this:

class Job {
  @prop()
  public title?: string;

  @prop()
  public position?: string;
}

class Car {
  @prop()
  public model?: string;
}

class User {
  @prop()
  public name?: string;

  @prop({ required: true })
  public age!: number; // This is a single Primitive

  @prop({ type: () => [String] })
  public preferences?: string[]; // This is a Primitive Array

  @prop()
  public mainJob?: Job; // This is a single SubDocument

  @prop({ type: () => Job })
  public jobs?: Job[]; // This is a SubDocument Array

  @prop({ ref: () => Car })
  public mainCar?: Ref<Car>; // This is a single Reference

  @prop({ ref: () => Car })
  public cars?: Ref<Car>[]; // This is a Reference Array
}

Extra Examples


Requirements & Install

Typegoose's Quick Start Guide

Testing

yarn install
yarn run test

Versioning

This Project should comply with Semver. It uses the Major.Minor.Fix standard (or in NPM terms, Major.Minor.Patch).

Join Our Discord Server

To ask questions or just talk with us, join our Discord Server.

Documentation

Known Issues

Here are the known-issues

FAQ

Here is the FAQ

Notes

  • Please don't add +1 or similar comments to issues. Use the reactions instead.