-
Notifications
You must be signed in to change notification settings - Fork 136
Validation failure because of invalid TypeScript enum configuration #196
Comments
passing enum to mongoose works, i dont know since when, but it works -> this can be closed |
I ran into this as well today. The issue only appears when using the I also found that the issue only appears if the enum is being referenced from another file — if it’s in the same file, there’s no problem. You can try it out by cloning this gist: import { prop, Typegoose } from 'typegoose';
import { MyEnum } from './enum';
class MySchema extends Typegoose {
@prop({ required: true, enum: MyEnum })
value!: MyEnum;
} export enum MyEnum {
foo = 'foo',
bar = 'bar',
}
I have no clue if this is an actual bug in either |
sorry, there is nothing we as typegoose maintainers could do about it (at least i cant...), because your code seems correct, and without the flag it dosnt give any compile errors which typegoose version did you use @LeoBakerHytch ? (could you try 6.0.0-22?) |
Hey, thanks for the quick response @hasezoey, and for the awesome work on this library! I updated the linked gist to use 6.0.0-22. Same story unfortunately, it’s still broken with I also added a test case with Reading around in the issues on the ts-node repo would suggest that it’s simply not possible to emit the correct type information without the type-checking step, which is what I’m really hoping to avoid. We’re using typegoose and ts-node on an API project that is incredibly slow to restart unless Would you consider a pull request to separate enum schema validation from string validation? At the same time I think it could be worth making it impossible to do the following: import { prop } from '@hasezoey/typegoose';
export enum Enum {
foo = 'foo',
}
class MySchema {
@prop({ enum: Enum, minlength: 4, maxlength: 1, match: 'not-foo' }) // 🚨OK
value?: Enum;
} Correct me if I’m wrong, but I don’t think it ever makes sense to have generic string validations on an enum field — in this contrived example, each of the string validations in fact conflicts with the only allowed value from the enum, but this currently passes validation. Roughly speaking, I propose to introduce an import { prop } from '@hasezoey/typegoose';
import { ExportedEnum } from './ExportedEnum';
type NotAnEnum = {};
class MySchema {
@enumProp({ enum: ExportedEnum })
value?: NotAnEnum; // 🚨 Mistake, but would pass validation
} I don’t think it’s any less safe than import { arrayProp } from '@hasezoey/typegoose';
class MySchema {
@arrayProp({ items: String })
value?: number[]; // 🚨 Also a mistake, but passes validation
} To avoid complicating the I think this could be done as a non-breaking change, although arguably Incidentally, I’ve had no response yet to my issue on ts-node (TypeStrong/ts-node#873), but I’m expecting that it won’t be possible to fix the issue there. Either way, I think I’ve updated the gist, and you can run |
By the way, I spotted a mistake in the docs for class Car extends Typegoose {}
class Shop extends Typegoose {}
// in another class
class Another extends Typegoose {
@prop({ required: true, enum: 'Car' | 'Shop' })
which!: string;
@arrayProp({ itemsRefPath: 'which' })
items?: Ref<Car | Shop>[];
} I guess Happy to roll fixing that into a PR if you like. |
sorry i dont know what this options does, and typegoose is not designed to be isolated...
i generally appreciate PR's, but to accept it, it must meet the guidelines and then on the implementation (but on this specific case, i will first look into it)
Yes i know the validation is wrong, but because typescript is just a pre-processor, and not an actual language, and reflect-metadata dosnt output nested things, it is not possible to infer the type of an array...
why shouldnt it be fixable there?
couldn't you just first compile it with tsc, and then execute from there? (to remove the ts-node step)
true, will get fixed
i know, but mongoose allows it because if enum's prop is a string, string validation can be applied did i miss something? |
Additional Note: this is the currently only instance enum is used in the prop file, and otherwise the handling of enum dosnt differ from the normal prop, so i think an "enumProp" would be too much, unlike an arrayProp, which is needed because it has many different options, incompatible options, or an "mapProp" because map is needed for more type infomation and option handling |
- README: change bitwise OR to array in "itemsRefPath"
a note got added in 806e870 to show that this module should not be used with that option alone |
I think you’re right that Digging into issues on ts-node and TypeScript some more, I found this comment on an issue which I think explains my problem:
This is in reference to an issue about incorrect reflected types — basically the same problem as I’m having with the imported enum not being reflected as So, I realised that the workaround was right in front of me the whole time: it’s as simple as just not importing the enum in the first place, but defining it in the same file as the schema 🤦♂ (For context, the reason to use ts-node without type-checking is that it’s incredibly slow, at least for the project I’m working on. I’m using it in conjunction with Thanks for updating the docs with the warning by the way! Hopefully this issue doesn’t have to trip anyone else up. |
@Ben305 this can be closed as "fixed? (v6.0.0)" |
TypeScript Enums are configured as
type: Object
, which is wrong, hence mongoose doesn't validate the enum fields correctly which results to persist incorrect values outside of enum definition into database.The text was updated successfully, but these errors were encountered: