You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When running ts-node --transpile-only, a class field declared with an imported (string) enum gets annotated as an Object, rather than the expected String.
This causes a problem with typegoose, which uses decorators to annotate a MongoDB / Mongoose database schema. Its prop decorator runs some validations to ensure consistency between the specified field type and the constraints provided in the decorator options.
Specifically, it checks that a field decorated with @prop({ enum: MyStringEnum }) is actually a string field. With --transpile-only enabled, this check always fails (this validation was added fairly recently: szokodiakos/typegoose@7418c34).
import'reflect-metadata';import{ExternalEnum}from'./enum-metadata';enumLocalEnum{bar='bar'}classClass{
@prop()local: LocalEnum;// OK
@prop()external: ExternalEnum;// Errors only with --transpile-only: Type === Object}functionprop(){returnfunction(target,key){constType=Reflect.getMetadata('design:type',target,key);if(Type!==String){throwError(`Expected String for field "${key}"; got ${Type.name}`);}};}
For comparison, TypeScript does emit the correct output when transpiling with isolatedModules: true:
tslib_1.__decorate([
prop(),
tslib_1.__metadata("design:type", String) // <—— what we want
], Class.prototype, "external");
index.js:
"use strict";
exports.__esModule = true;
var tslib_1 = require("tslib");
require("reflect-metadata");
var enum_metadata_1 = require("./enum-metadata");
var LocalEnum;
(function (LocalEnum) {
LocalEnum["bar"] = "bar";
})(LocalEnum || (LocalEnum = {}));
var Class = /** @class */ (function () {
function Class() {
}
tslib_1.__decorate([
prop(),
tslib_1.__metadata("design:type", String)
], Class.prototype, "local");
tslib_1.__decorate([
prop(),
tslib_1.__metadata("design:type", String)
], Class.prototype, "external");
return Class;
}());
function prop() {
return function (target, key) {
var Type = Reflect.getMetadata('design:type', target, key);
if (Type !== String) {
throw Error("Expected String for field \"" + key + "\"; got " + Type.name);
}
};
}
Solution?
Is there any way around this other than enabling --type-check or disabling --transpile-only? (I’m not actually clear on whether those two flags are complementary — does it make any sense to use both flags?)
We have been using --transpile-only as restarts of our server are incredibly slow without it... it would be a shame to have to disable it.
I’m not sure where the best place is to solve this issue. The additional validation added in Typegoose to ensure consistency of field types & constraints makes sense, so I wouldn’t really like to suggest that it be weakened for the sake of an environment-specific problem.
The text was updated successfully, but these errors were encountered:
You would only need one of either --type-check or --transpile-only (--type-check is there for backward compatibly and not documented anywhere as far as I know).
Unfortunately this is just how the TypeScript compiler works. For certain use-cases (such as these enums), TypeScript requires type information to compile correctly. If it needs type information, --transpile-only will be incapable of generating the expected output.
Problem
When running
ts-node --transpile-only
, a class field declared with an imported (string) enum gets annotated as anObject
, rather than the expectedString
.This causes a problem with typegoose, which uses decorators to annotate a MongoDB / Mongoose database schema. Its
prop
decorator runs some validations to ensure consistency between the specified field type and the constraints provided in the decorator options.Specifically, it checks that a field decorated with
@prop({ enum: MyStringEnum })
is actually a string field. With--transpile-only
enabled, this check always fails (this validation was added fairly recently: szokodiakos/typegoose@7418c34).Repro
Can be cloned from https://gist.github.com/LeoBakerHytch/a45a6ed03b27807def5ec799d5a56c26
index.ts:
enum-metadata.ts:
package.json scripts:
Compiled output
For comparison, TypeScript does emit the correct output when transpiling with
isolatedModules: true
:index.js:
Solution?
Is there any way around this other than enabling
--type-check
or disabling--transpile-only
? (I’m not actually clear on whether those two flags are complementary — does it make any sense to use both flags?)We have been using
--transpile-only
as restarts of our server are incredibly slow without it... it would be a shame to have to disable it.Related
The relavant Typegoose issue is szokodiakos/typegoose#196.
I’m not sure where the best place is to solve this issue. The additional validation added in Typegoose to ensure consistency of field types & constraints makes sense, so I wouldn’t really like to suggest that it be weakened for the sake of an environment-specific problem.
The text was updated successfully, but these errors were encountered: