⚒️

JSオブジェクトに対しTypeScriptのOmitとPickみたいなことがやりたい

2024/02/12に公開

はじめに

TypeScriptが提供するUtilityTypesとは、コード内での型変換を容易にする為の(便利な関数のような)型達です。
その中でもOmitPickは、型レベルでオブジェクトのプロパティを選択したり除外したりする非常に便利な存在です。
今回は、このOmitPickのような挙動を実際のオブジェクト(JSオブジェクト)に対し再現する便利関数の実装を紹介します。

Omit関数の実装

こちらのomit関数は、指定したキーを除外した新しいオブジェクトを作成します。

export const omit = <
  T extends Record<string, unknown>,
  K extends [keyof T, ...(keyof T)[]]
>(
  obj: T,
  ...keys: K
): Omit<T, K[number]> => {
  const result = { ...obj };
  for (const key of keys) {
    if (key in result) delete result[key];
  }
  return result;
};

Pick関数の実装

omitとは対照的に、pick関数は、指定したキーのみを含む新しいオブジェクトを作成します。

export const pick = <
  T extends Record<string, unknown>,
  K extends [keyof T, ...(keyof T)[]]
>(
  obj: T,
  ...keys: K
): Pick<T, K[number]> => {
  const result = {} as Pick<T, K[number]>;
  for (const key of keys) {
    if (key in obj) result[key] = obj[key];
  }
  return result;
};

実際の使用例

type FavoriteWhisky = {
  yamazaki: "白州";
  hakusyu: "山崎";
  glenfarclas: "グレンファークラス";
  laphroaig: "ラフロイグ";
}

const favoriteWhisky: FavoriteWhisky = {
  yamazaki: "白州";
  hakusyu: "山崎";
  glenfarclas: "グレンファークラス";
  laphroaig: "ラフロイグ";
};

const scotch = omit(favoriteWhisky, "yamazaki", "hakusyu");
const japanese = pick(favoriteWhisky, "yamazaki", "hakusyu");

console.log({scotch,japanese})
// ログ
// "scotch": {
// "glenfarclas": "グレンファークラス",
// "laphroaig": "ラフロイグ"
// },
// "japanese": {
// "yamazaki": "白州",
// "hakusyu": "山崎"
// }

まとめ

TypeScriptのOmitとPickは型レベルでの操作に非常に有用なので、実際のオブジェクト操作においても同様の操作ができると結構便利で自分は気に入っています。小ネタ的な記事ですが、少しでもお役に立てたら幸いです!「もっとこの書き方の方が良い!」みたいなご意見もいただけると嬉しいです😊

株式会社ZOZO

Discussion