Definitelytyped: mongoose ObjectId

Created on 18 Dec 2014  路  9Comments  路  Source: DefinitelyTyped/DefinitelyTyped

I am defining a Schema which includes a type ObjectId. In my JavaScript I would use mongoose.Schema.Types.ObjectId but when I convert it to Typescript I get the following error:

error TS2305: Module '"mongoose"' has no exported member 'Schema'.

This is odd because there is definitely an export class Schema in the typescript definition with a static Types property.

here is my Typescript code

import mongoose = require('mongoose');

export interface IManagerSchema extends mongoose.Document {
  user: mongoose.Schema.ObjectId;
}

export var ManagerSchema = new mongoose.Schema({
  user: {
    type: mongoose.Schema.ObjectId,
    ref: 'User',
    required: true
  }
});

I've been trying to work this out for a couple of days now so any help would be really appreciated

Most helpful comment

I looked into this a little further and discovered how to get your code to compile. Note the introduction of the keyword typeof in two places:

/// <reference path='mongoose.d.ts' />
import mongoose = require('mongoose');

export interface IManagerSchema extends mongoose.Document {
  user: typeof mongoose.Schema.Types.ObjectId;
}

export var ManagerSchema = new mongoose.Schema({
  user: {
    type: typeof mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true
  }
});

Note that there is an issue with the particular compiler error that was being issued. See this issue: https://github.com/Microsoft/TypeScript/issues/722

All 9 comments

@horiuchi @psnider do you have something advise?

I use this code:

import mongoose                         = require('mongoose');
var id = new mongoose.Types.ObjectId;

I use this code in my model module:

import mongoose = require('mongoose');

export class ObjectId implements mongoose.Types.ObjectId {}

I also found that I have used this:

import mongoose                         = require('mongoose');
var ObjectId                            = mongoose.Schema.Types.ObjectId;

because

import mongoose                         = require('mongoose');
import ObjectId                            = mongoose.Schema.Types.ObjectId;

gives this error:

test.ts(22,1): error TS2305: Module '"mongoose"' has no exported member 'Schema'.

I looked into this a little further and discovered how to get your code to compile. Note the introduction of the keyword typeof in two places:

/// <reference path='mongoose.d.ts' />
import mongoose = require('mongoose');

export interface IManagerSchema extends mongoose.Document {
  user: typeof mongoose.Schema.Types.ObjectId;
}

export var ManagerSchema = new mongoose.Schema({
  user: {
    type: typeof mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true
  }
});

Note that there is an issue with the particular compiler error that was being issued. See this issue: https://github.com/Microsoft/TypeScript/issues/722

Genius, of course that does make sense I'll give that a go a bit later. Cheers

sorry, that did compile but it outputs type: typeof mongoose.Schema.Types.ObjectId in the javascript.

I tried mongoose.Types.ObjectId which works but it is actually different to mongoose.Schema.Types.ObjectId so all the tests broke :wink:

It appears that typeof is treated differently in different contexts: in some it is a TypeScript keyword, and in others it is treated as a javascript keyword. I haven't yet figured out when or why it differs.

But I played with your code a bit more and think I may have a solution, by using the Types module instead of the reference from within Schemas. Again, I don't know enough about TypeScript namespaces to answer why. Perhaps this will work for you:

/// <reference path='mongoose.d.ts' />
import mongoose = require('mongoose');
import Schema = mongoose.Schema;
import Types = mongoose.Types;
import ObjectId = Types.ObjectId;

export interface IManagerSchema extends mongoose.Document {
  user: ObjectId;
}

export var ManagerSchema = new mongoose.Schema({
  user: {
    type: ObjectId,
    ref: 'User',
    required: true
  }
});

I found out the ObjectId type is now defined under Types only when you are using package @types/mongoose
so you should use it like this
import mongoose from 'mongoose';
const ObjectId = mognoose.Types.ObjectId

Was this page helpful?
0 / 5 - 0 ratings