null2undefined関数とundefined2null関数の紹介
こんにちわ。nap5です。
null2undefined関数とundefined2null関数の紹介をしたいと思います。
デモのドメインです。nullish(nullとundefinedを含む)でUnNeatな型になります。スキーマはzodライブラリで定義しています。
import { z } from "zod";
const BlogDataSchema = z.object({
id: z.number().nullish(),
title: z.string().nullish(),
published: z.boolean().nullish(),
});
const AuthorDataSchema = z.object({
id: z.number().nullish(),
name: z.string().nullish(),
age: z.number().nullish(),
blogs: BlogDataSchema.array().nullish(),
});
type UnNeatData = z.infer<typeof AuthorDataSchema>;
デモデータです。
const data: UnNeatData = {
id: null,
name: "Jack Jackson",
age: 38,
blogs: [
{
id: null,
title: "AAA",
published: false,
},
{
id: 2,
title: null,
published: false,
},
{
id: null,
title: null,
published: true,
},
],
};
DeepNonNullableはts-essentialsライブラリから使えますが、DeepNonUndefinedは以下の記事から流用してみました。
type PrimitiveOmitNull =
| number
| string
| boolean
| bigint
| symbol
| undefined;
type BuiltinOmitNull =
| PrimitiveOmitNull
| Function
| Date
| Error
| RegExp;
// https://qiita.com/irico/items/ca02ba3ebf21fc96b062
// https://www.gaji.jp/blog/2022/09/02/10867/
type DeepNonUndefined<T> = T extends BuiltinOmitNull
? NonNullable<T>
: { [key in keyof T]-?: DeepNonUndefined<T[key]> };
タイトルの関数になります。
const null2undefined = <T>(data: unknown): T => {
const flatData: Record<string, unknown> = flatten(data);
Object.keys(flatData).forEach((key) => {
flatData[key] = flatData[key] === null ? undefined : flatData[key];
});
return unflatten(flatData);
};
const undefined2null = <T>(data: unknown): T => {
const flatData: Record<string, unknown> = flatten(data);
Object.keys(flatData).forEach((key) => {
flatData[key] = flatData[key] === undefined ? null : flatData[key];
});
return unflatten(flatData);
};
最後に定義した関数を使ってみます。
type UnNeatInBoundData = DeepNonNullable<UnNeatData>;
type UnNeatOutBoundData = DeepNonUndefined<UnNeatData>;
console.log(data);
const result1 = null2undefined<UnNeatInBoundData>(data); // from db to web <<< InBound
console.log(result1);
const result2 = undefined2null<UnNeatOutBoundData>(result1); // from web to db >>> OutBound
console.log(result2);
実行結果です。
nullがundefinedに置換されてインバウンド(from db to web)を達成でき、undefinedがnullに置換されてアウトバウンド(from web to db)を達成できているようです。
$ yarn do
{
id: null,
name: 'Jack Jackson',
age: 38,
blogs: [
{ id: null, title: 'AAA', published: false },
{ id: 2, title: null, published: false },
{ id: null, title: null, published: true }
]
}
{
id: undefined,
name: 'Jack Jackson',
age: 38,
blogs: [
{ id: undefined, title: 'AAA', published: false },
{ id: 2, title: undefined, published: false },
{ id: undefined, title: undefined, published: true }
]
}
{
id: null,
name: 'Jack Jackson',
age: 38,
blogs: [
{ id: null, title: 'AAA', published: false },
{ id: 2, title: null, published: false },
{ id: null, title: null, published: true }
]
}
Done in 0.95s.
デモコードです。
簡単ですが、以上です。
この記事が気に入ったらサポートをしてみませんか?