class-validator
class-validator copied to clipboard
fix: `@IsEnum()` does not error when enum-key is used instead of enum-value
Description
When using an enum-key instead of enum-value it should throw an error but doesnt.
enum Direction {
Up = 0,
Down,
Left,
Right,
}
class myClass {
@IsEnum(Direction)
direction: Direction;
}
Now the following will be valid: const obj = { direction: 'Down'; }
Expected behavior
It should add an error.
Actual behavior
Does not add an error.
Workaround
Use IsIn() instead, e.g. by use of ts-enum-util to create an array of the enum-values:
class myClass {
@IsIn($enum(Direction).getValues())
direction: Direction;
}
Results in:
isIn: 'direction must be one of the following values: 0, 1, 2, 3'
Confirmed for 0.14.0.
The minimal reproduction case:
import { IsEnum, validate } from 'class-validator';
enum Direction {
Up = 0,
Down,
Left,
Right,
}
class MyPayload {
@IsEnum(Direction)
value: Direction;
constructor(direction?: Direction) {
this.value = direction;
}
}
// Will pass
validate(new MyPayload(Direction.Up)).then(console.log);
validate(new MyPayload(Direction.Down)).then(console.log);
// SHOULD FAIL
validate(new MyPayload('Up' as any as Direction)).then(console.log);
validate(new MyPayload('Down' as any as Direction)).then(console.log);
Bumped into the same issue, version 0.14.0
enum MyEnum {
Alpha = 1,
Beta = 2,
}
class TestClass {
@IsEnum(MyEnum)
myEnumVal: any;
}
const inst = new TestClass();
inst.myEnumVal = 'Alpha';
console.log(validateSync(inst));
The issue comes from the function:
export function isEnum(value: unknown, entity: any): boolean {
const enumValues = Object.keys(entity).map(k => entity[k]);
return enumValues.includes(value);
}
Specifically this line
const enumValues = Object.keys(entity).map(k => entity[k]);
An enum will become this in javascript:
var MyEnum;
(function (MyEnum) {
MyEnum[MyEnum["Alpha"] = 1] = "Alpha";
MyEnum[MyEnum["Beta"] = 2] = "Beta";
})(MyEnum || (MyEnum = {}));
When running Object.keys(MyEnum) we will get this:
Object.keys(MyEnum)
['1', '2', 'Alpha', 'Beta']