🤔

ObjectのPropertiesをPick/Omitしたい

2022/01/17に公開

TL;DR

強制キャストしているゴリ押しコードですが下記のようになりました。
もっと良さそうな方法や書き方があれば是非コメントで教えて下さい。

/**
 * オブジェクトから指定したプロパティのみを抽出したオブジェクトを返す
 * @param instance 元になるオブジェクト
 * @param pickProperties 抽出するプロパティ
 * @returns 抽出後のオブジェクト
 */
export function pickProperties<K>(
  instance: K extends object ? K : never,
  ...pickProperties: (keyof K)[]
): Pick<K, (typeof pickProperties)[number]> {
  return <Pick<K, (typeof pickProperties)[number]>>pickProperties.reduce<
    Partial<K>
  >((i, p) => {
    if (p in instance) i[p] = instance[p];
    return i;
  }, {});
}

/**
 * オブジェクトから指定したプロパティを削除したオブジェクトを返す
 * @param instance 元になるオブジェクト
 * @param omitProperties 削除するプロパティ
 * @returns 削除後のオブジェクト
 */
export function omitProperties<K>(
  instance: K extends object ? K : never,
  ...omitProperties: (keyof K)[]
): Omit<K, (typeof omitProperties)[number]> {
  return <Omit<K, (typeof omitProperties)[number]>>omitProperties.reduce<
    Partial<K>
  >(
    (i, p) => {
      delete i[p];
      return i;
    },
    Object.assign({}, instance)
  );
}

どうして黒魔術に手を染めたのですか?

"あるクラスの一部のプロパティを除いた残りのプロパティ"を使いたかった。プロパティが増えるたびにコードを書き直すのが面倒だった。TypeScriptのUtility Typesのように書けたら便利だと思った。後悔はしていない。
(職業:自称システムエンジニア 30代・男性)

Discussion