Skip to content
This repository has been archived by the owner on Jun 29, 2021. It is now read-only.

TypeError: Class constructor Typegoose cannot be invoked without 'new' #60

Closed
anvlkv opened this issue Oct 15, 2017 · 13 comments
Closed
Labels

Comments

@anvlkv
Copy link

anvlkv commented Oct 15, 2017

Hi,
I'm for some reason getting this error "TypeError: Class constructor Typegoose cannot be invoked without 'new'"

I have a class like this:

export class Item extends Typegoose {
	@prop()
	name: string;

	@prop()
	description: string;

	@prop({ref: Asset})
	question: Asset;

	@prop({enum: ItemTypes})
	itemType: ItemTypes;

	@prop({enum: ItemModes})
	itemMode: ItemModes;
}

I also have service which uses the class like this:

export class ItemsService {
	private itemModel;

	constructor(
	) {
		this.itemModel = new Item().getModelForClass(Item);
	}
}

As TS compiles:

TypeError: Class constructor Typegoose cannot be invoked without 'new'
    at new Item (/Users/anvlkv/Projects/intervey/intervey-api/src/models/item.ts:40:42)
    at new ItemsService (/Users/anvlkv/Projects/intervey/intervey-api/src/server/services/itemsService.ts:11:20)
    at new SequenceService (/Users/anvlkv/Projects/intervey/intervey-api/src/server/services/sequenceService.ts:13:23)
    at Object.<anonymous> (/Users/anvlkv/Projects/intervey/intervey-api/src/server/routes/InterviewerRoutes.ts:9:42)
    at Module._compile (module.js:570:32)
    at Module.m._compile (/Users/anvlkv/Projects/intervey/intervey-api/node_modules/ts-node/src/index.ts:392:23)
    at Module._extensions..js (module.js:579:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/Users/anvlkv/Projects/intervey/intervey-api/node_modules/ts-node/src/index.ts:395:12)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/anvlkv/Projects/intervey/intervey-api/src/server/main.ts:4:1)
    at Module._compile (module.js:570:32)
    at Module.m._compile (/Users/anvlkv/Projects/intervey/intervey-api/node_modules/ts-node/src/index.ts:392:23)
[nodemon] app crashed - waiting for file changes before starting...

The strangest part is that my src/models/item.ts is only 33 lines and problem supposed to be at line 40.

@pgsfredda
Copy link

Hi @anvlkv.
Try in this manner:

export const ItemModel = new Item().getModelForClass(Item);

export class ItemsService {
	private itemModel: InstanceType<Item>;

	constructor(
	) {
		this.itemModel = new ItemModel({ /* here you can put some field to inizialize */ });
	}
}

@anvlkv
Copy link
Author

anvlkv commented Oct 17, 2017

Hi @pgsfredda,

Thanks for looking into my problem

I tried your suggestion, it just shifted the error to where I export const ItemModel

I've got this repo with reproduction

@pgsfredda
Copy link

pgsfredda commented Oct 17, 2017

Hi @anvlkv
I have understand your problem. The correct source is:

import { prop, Typegoose } from 'typegoose';

export class Item extends Typegoose {
	@prop()
	name: string;

	@prop()
	description: string;
}

export const ItemModel = new Item().getModelForClass(Item); //Here is the correction. The type of ItemModel is inferred

let trial = new ItemModel({name:'some', description:'some'});

console.log(trial);
// prints:
// {    name: 'some',
//      description: 'some',
//      _id: 59e65dcf24b047492f48e13f }

By the way, no monogoose Model is needed. ItemModel represents the schema and the collection of data with the two fields 'name' and 'description' and all the statics, the methods and the plugins.
If you want to declare e function param you can use:

function( item: InstanceType<Item>) { ... }

@anvlkv
Copy link
Author

anvlkv commented Oct 17, 2017

@pgsfredda Hmmm,

Still got the same issue.

If I'm not declaring type like export const ItemModel: Model<InstanceType<Item>> I get typescript error TS4023:
Error:(11, 14) TS4023:Exported variable 'ItemModel' has or is using name 'Document' from external module "mongoose" but cannot be named.
Error:(11, 14) TS4023:Exported variable 'ItemModel' has or is using name 'Model' from external module "mongoose" but cannot be named.

According to this microsoft/TypeScript#5711 solution is to declare it.

Since in this example I have it all in one file I can even ignore export and just do const ItemModel = new Item().getModelForClass(Item) as you suggested.

@pgsfredda
Copy link

@anvlkv
I don't undestand why.
My source example works correctly. I use that pattern always and works fine.
Of course, you have to use 'export' instruction to use ItemModel in other files.

The pattern for the 'model file' is:

import { Typegoose, prop } from 'typegoose';

export class Item exrends Typegoose {
   @prop() field: simple type of field (string, number, ...)
   ...
};

export const ItemModel = new Item().getModelForClass(Item);

Then you can use ItemModel to active find, update and create methods in the other files.

Check also your grunt and tsconfig files for the options about decorations (see the README.md file).

@derekhawker
Copy link

I had the same error as the initial post It was caused by a tsconfig.json setting (target: "es5"). Setting target to "es6" fixed the errors. I guess es5 functions are not a direct replacement for class inheritance in this case.

Hope this catches the eye of anyone with a similar issue. On my end it was mostly just a copy+paste problem since I use typescript with web projects usually and using es6 there isn't really great for compatibility.

@szokodiakos
Copy link
Owner

Thanks for trying to resolve the issue @pgsfredda and @derekhawker .

So if I undestand this right: Typegoose will not work with TypeScript projects targeted to "es5" right, only es6/es2015 ? @anvlkv can you try out your code with target set to es6 and post us the results?

If that is the case I'll have to add this note to the documentation (or try to find a way to make Typegoose es5 target compatible)

@anvlkv
Copy link
Author

anvlkv commented Oct 18, 2017

Cool! Thank you guys! That totally helped.

I don't have any need to use other targets.

update: or may be I actually do))

@anvlkv anvlkv closed this as completed Oct 18, 2017
@anvlkv anvlkv reopened this Oct 18, 2017
@ndoulgeridis
Copy link

ndoulgeridis commented Jun 2, 2018

Sorry recovering this issue but is Typegoose now ES5 compatible? I still get this error when I use es5 and I need es5 as a target.

@singhsoldier13
Copy link

I am facing this issue as well and I cannot use ES6 as target in my project. Is there any way I can make this work with ES5?

@rolivegab
Copy link

Are there any plans for Typegoose be compatible with target ES5?

@singhsoldier13
Copy link

singhsoldier13 commented Dec 2, 2018 via email

@Tom4U
Copy link

Tom4U commented Dec 22, 2018

It's a real issue, as Angular's test (spec) files cannot be run properly, if I try to use a model that is based on Typegoose. Will you take over ES5 compatibility from @singhsoldier13 in future??

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

9 participants