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.
 
 
 
hasezoey 4be10be9c7
docs(error-warning-details): fix broken links for W002
2 days ago
.github chore(workflows::website-pr): rename workflow to reflect what it does 2 months ago
.husky chore(husky): upgrade to version "6.0.0" 2 years ago
.vscode chore(vscode/tasks): disable auto-run of tasks 6 months ago
docs docs(error-warning-details): fix broken links for W002 2 days ago
src fix(typegoose::getDiscriminatorModelForClass): add warning when using different "existing*" options 2 days ago
test fix(typegoose::getDiscriminatorModelForClass): add warning when using different "existing*" options 2 days ago
website chore(website/yarn.lock): lockfile maintenance 2 days ago
.editorconfig enable "strictNullChecks" 3 years ago
.eslintignore style: fix some typos (#754) 6 months ago
.eslintrc.js style: fix some typos (#754) 6 months ago
.gitignore Add Inheritance Tests 3 years ago
.npmignore Small Changes 3 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) 6 months ago
CHANGELOG.md release: v10.1.1 2 days ago
LICENSE chore(LICENSE): update for 2022 6 months ago
README.md docs(README): remove "as" assertion from example 2 months ago
commitlint.config.js style: apply eslint rules to top level and website js files 1 year ago
ghPagesPre.sh chore(ghPagesPre): fix script (exit on error) 1 year ago
jest.config.json dependencies(jest): upgrade to 29.0.3 2 months ago
jest.config.tsd.json chore: add tsd-lite as jest tests 7 months ago
lint-staged.config.js style: apply eslint rules to top level and website js files 1 year ago
package.json release: v10.1.1 2 days ago
tsconfig.build.json style: apply eslint rules to top level and website js files 1 year ago
tsconfig.buildTests.json chore: exclude ".test-d.ts" files from "build:tests" script 2 months ago
tsconfig.json feat(tsconfig.json): update "target" to match minimal NodeJS capabilities 2 months ago
yarn.lock chore(deps): bump http-cache-semantics from 4.1.0 to 4.1.1 (#788) 3 days 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)

  • 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.