私の「AppState」列挙には、次の可能な列挙値があります。
export enum AppState {
SUCCESS,
ERROR,
RUNNING
}
[UpdateAppStateDTOとappState
を使用します。これは[〜#〜] running [〜#〜]以外のすべての列挙値を受け入れる必要があります。
export class UpdateAppStateDTO {
@IsEnum(AppState)
@NotEquals(AppState.RUNNING) // Doesn't work properly
public appState: AppState;
}
ルートについては、この例があります
@Patch()
public setState(@Body() { appState }: UpdateAppStateDTO): void {
console.log(appState);
}
リクエストの本文が空であるか、appState
の「foobar」などの無効な列挙値がある場合、400が返されます。
問題は、「RUNNING」を送信したときに、400ではなく200が引き続き取得されることです。
この動作を防ぐにはどうすればよいですか?
問題は、「RUNNING」を送信しても、400ではなく200が引き続き取得されることです。
次のように、リクエストペイロードの値としてstring(!) "RUNNING"を使用しているようです:
_{ appState: "RUNNING" }
_
この場合、IsEnum
とNotEquals
はどちらもペイロードを有効と見なします。
それはなぜですか?
まず最初に 数値列挙はTypeScriptによって逆マッピングされます なので、列挙は内部的に(JavaScriptオブジェクトとして)次のように表されます。
_{
'0': 'SUCCESS',
'1': 'ERROR',
'2': 'RUNNING',
SUCCESS: 0,
ERROR: 1,
RUNNING: 2
}
_
ここで、クラスバリデーターのisEnum()
次のようにコーディングされます :
_isEnum(value: unknown, entity: any): boolean {
const enumValues = Object.keys(entity)
.map(k => entity[k]);
return enumValues.indexOf(value) >= 0;
}
_
列挙型が逆マップされているため、isEnum('RUNNNING', AppState)
はtrueを返します。
同時にNotEquals
、これは そのようにコーディングされています ...
_notEquals(value: unknown, comparison: unknown): boolean {
return value !== comparison;
}
_
文字列 'RUNNING'を_AppState.RUNNING
_(_2
_と同等)と比較し、これは_'RUNNING' != 2
_以降有効であると結論付けます。
つまり、ペイロード_{ appState: "RUNNING" }
_がステータスコード400ではなく200になる理由がわかります。
この動作を防ぐにはどうすればよいですか?
列挙値_AppState.RUNNING
_は_2
_と同等であるため、リクエストを行うときは、ペイロードで_2
_の数値を使用する必要があります。
_{ appState: 2 }
_
上記の場合、クラスバリデーターのNotEquals
バリデーターは、次の内容を含む応答でリクエストを正しく拒否します。
_"constraints": {
"notEquals": "appState should not be equal to 2"
}
_