LoginSignup
0
0

More than 1 year has passed since last update.

TypeScriptでLaravel製APIのバリデーションエラーのレスポンスボディに型をつける(型ガード付き)

Last updated at Posted at 2022-04-14

タイトルの通り、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の部分)が文字列としかチェックしようがないので、全然違うプロパティ名が入っても通ってしまうことです。
もし改善案があればコメントお願いします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0