特定のキーを除く型(Omitをネストさせる)

type NestedOmit<T, K extends keyof T> = {
    [P in keyof Omit<T, K>]: T[P] extends Array<infer R>
        ? K extends keyof R 
            ? Array<NestedOmit<R, K>>
            : Array<R>
        : K extends keyof T[P]
            ? NestedOmit<T[P], K>
            : T[P]
};

例えばレシピとその材料を表す以下のinterfaceがあったとき

interface Recipe {
  id: number;
  name: string;
  ingredients: Ingredient[];
}

interface Ingredient {
  id: number;
  name: string;
}

作成apiにpostするデータとしては、idは不要。そのデータにつけるための型を用意する場合、色々やり方はあるが、例えば以下のようにしなければいけない

interface PostData {
  name: string;
  ingredients: Omit<Ingredient, "id">[];
}

idが共通して不要な場合、これはめんどくさいし、元のRecipeの型が変わったとき変更についていくのがだるそう

ので、冒頭に書いたようなねすとするOmitを定義してみた。

type PostData = NestedOmit<Recipe, "id">;

楽でいいな〜と思いつつ、こういうのってみなさんどうしてるんですかねと思った