zodライブラリを使ってプロパティの包含と除外の機能をもつuseCludeというフックを作ってみました
こんにちわ。nap5です。今回は小ネタです。
zodライブラリを使ってプロパティの包含と除外の機能をもつuseCludeというフックを作ってみました。
PrismaのDSLみたいに宣言的に抽出対象を指定したりできたら、便利だと思いチャレンジしてみました。もう少し仕上げる必要はあるかもしれませんが、このぐらいのほうがハンディかもです。
前回の記事と関連です。
データです。
[
{
"id": "p9z7aek9fi",
"name": "Landon Glover",
"age": 38,
"blogs": []
},
{
"id": "pga7t8prpl",
"name": "Jack Jackson",
"age": 38,
"blogs": [
{
"id": "1",
"title": "AAA"
},
{
"id": "2",
"title": "BBB"
},
{
"id": "3",
"title": "CCC"
}
]
},
{
"id": "tcz4kesu6p",
"name": "Grace Dennis",
"age": 44,
"blogs": [
{
"id": "4",
"title": "DDD"
}
]
}
]
useCludeフックです。
import { z } from "zod";
const useClude = (shape: z.ZodRawShape) => {
const schema = z.object(shape);
type Shape = z.infer<typeof schema>;
type ShapeKeys = keyof Shape;
const exclude = (...props: ShapeKeys[]) => {
return schema.transform((res) => {
const items = Object.keys(res) as ShapeKeys[];
return items
.filter((item) => {
return !props.includes(item);
})
.reduce((acc, cur) => {
return { ...acc, [cur]: res[cur] };
}, {});
});
};
const include = (...props: ShapeKeys[]) => {
return schema.transform((res) => {
const items = Object.keys(res) as ShapeKeys[];
return items
.filter((item) => {
return props.includes(item);
})
.reduce((acc, cur) => {
return { ...acc, [cur]: res[cur] };
}, {});
});
};
return {
exclude,
include,
};
};
使い方です。
まずは指定したプロパティの包含です。
import data from "@/data/bebop.json";
const userShape: z.ZodRawShape = {
id: z.string(),
name: z.string(),
age: z.number(),
blogs: z
.object({
id: z.string(),
title: z.string(),
})
.array(),
};
const { exclude, include } = useClude(userShape);
console.log(
JSON.stringify(
data.map((item) => include("blogs").parse(item)),
null,
2
)
);
実行結果です。
[
{
"blogs": []
},
{
"blogs": [
{
"id": "1",
"title": "AAA"
},
{
"id": "2",
"title": "BBB"
},
{
"id": "3",
"title": "CCC"
}
]
},
{
"blogs": [
{
"id": "4",
"title": "DDD"
}
]
}
]
次に指定したプロパティの除外です。
import data from "@/data/bebop.json";
const userShape: z.ZodRawShape = {
id: z.string(),
name: z.string(),
age: z.number(),
blogs: z
.object({
id: z.string(),
title: z.string(),
})
.array(),
};
const { exclude, include } = useClude(userShape);
console.log(
JSON.stringify(
data.map((item) => exclude("name", "age").parse(item)),
null,
2
)
);
実行結果です。
[
{
"id": "p9z7aek9fi",
"blogs": []
},
{
"id": "pga7t8prpl",
"blogs": [
{
"id": "1",
"title": "AAA"
},
{
"id": "2",
"title": "BBB"
},
{
"id": "3",
"title": "CCC"
}
]
},
{
"id": "tcz4kesu6p",
"blogs": [
{
"id": "4",
"title": "DDD"
}
]
}
]
簡単ですが、以上です。
この記事が気に入ったらサポートをしてみませんか?