class-validatorで「null
だけ」とか「undefined
だけ」のような独自のバリデーションを実装したい場合に、カスタムバリデータ(カスタムデコレータ)が使えますという備忘録です。
前提
動作確認時のclass-validator
のversionは以下の通りです。
class-validator: v0.13.2
課題: nullとundefinedを個別に判定したい
IsOptional
@IsOptional()
を使うと、null
とundefined
の場合両方許容してしまいます。
参考: https://github.com/typestack/class-validator#validation-decorators の@IsOptional()
そのため、以下のようなケースでうまいことclass-validator
が機能しません。困った。
// nullableだけどundefinedではない
nullableString: string | null
// optionalだけどnullではない
optionalString?: stirng;
ValidateIf
特定条件を満たす場合にのみバリデーションするという条件をValidateIf
で付加できます。
参考: https://github.com/typestack/class-validator#conditional-validation
従って、例えば上記のoptionalString
に対するバリデーションでundefined
のみを許容したい場合、
@ValidateIf((_, value) => value !== undefined)
optionalString?: string;
と書けます。@ValidateIf(...)
をカスタムデコレータとして定義しておけば、
const IsUndefinedable = () => {
return ValidateIf((_, value) => value !== undefined)
}
~~~
@IsUndefindable()
optionalString?: string;
のように書けて便利です。
結論
ValidateIf
デコレータは便利です。
余談ですが、ValidateIfの第一引数では、当該ValidateIfが定義されている対象オブジェクトのプロパティを参照できるようなので、公式の例にあるように、別プロパティを使って条件組むことも可能です。
// https://github.com/typestack/class-validator#conditional-validationから引用
import { ValidateIf, IsNotEmpty } from 'class-validator';
export class Post {
otherProperty: string;
@ValidateIf(o => o.otherProperty === 'value')
@IsNotEmpty()
example: string;
}