タイトルの通り、Laravel製APIのバリデーションエラーのレスポンスにTSで型をつけていきます。フォームのリクエスト処理とかで便利かと。
まずレスポンスの見本を見ていきましょう。
{
"message": "The given data was invalid.",
"errors": {
"【リクエストボディのプロパティ名】" : ["【エラーメッセージ】","【エラーメッセージ2】]
}
}
errorsというプロパティ名なのにオブジェクトなのが紛らわしいのと、 エラーメッセージの配列が入ってるあたりに注意が必要です。
export type ValidationError<T> = {
message: string,
errors: Record<keyof T, Array<string>>
}
//あえて"=="で比較するだけでnull&undefinedを最小のコードで検出できる
const isNullOrUndefined = (unknown: unknown): boolean => unknown == null
export const isValidationError = <T>(unknown: unknown): unknown is ValidationError<T> => {
if (isNullOrUndefined(unknown)) { return false }
if (typeof unknown !== "object") { return false }
const validationError = unknown as ValidationError<T>
if (typeof validationError?.message !== "string") { return false }
if (typeof validationError?.errors !== "object") { return false }
return Object.entries(validationError.errors)
.every(
([property, messages]) => {
return typeof property === "string" &&
Array.isArray(messages) &&
messages.every(message => typeof message === "string")
}
)
}
認識してる欠陥としては、errorsオブジェクトのプロパティ(keyof T
の部分)が文字列としかチェックしようがないので、全然違うプロパティ名が入っても通ってしまうことです。
もし改善案があればコメントお願いします。