💎
【Zod】string型の"true", "false"をboolean型のtrue, falseに変換する
はじめに
何がしたかったか
文字列として存在する"true"
と"false"
をzodでbooleanにしてtrue
とfalse
に直そうとしました。
全部trueになってしまう!
とりあえず定義
const a = z.coerce.boolean();
"true"
はもちろんtrue
になります。
a.parse("true") // true
しかし、"false"
もtrue
になってしまいます...
a.parse("false") // true
この挙動はJavaScriptのBoolean()
と似ています。
> Boolean("false")
true
解決法
過去に同じ問題で悩んでいる方が居たので、そこから解決策を引っ張り出します。 (colinhacks/zod/issues/2985)
シンプルにやる ("true", "false"のみ)
単純に"true"と"false"をparseしたいだけならこれが使えます。
z.enum(['true', 'false']).transform((value) => value === 'true')
使ってみると...
const b = z.enum(["true", "false"]).transform((value) => value === "true")
b.parse("true") // true
b.parse("false") // false
"true"はtrue、"false"はfalseとなり、期待通りの結果が得られました。
ちゃんとやる (+ "True", "False", "0", "1")
"true"だけではなく"True", "False", "1", "0", 1, 0もparseできるようにしたい場合はこれが良さそうです。preprocessを活用しています。
const castStringToBool = z.preprocess((val) => {
if (typeof val === "string") {
if (['1', 'true'].includes(val.toLowerCase())) return true;
if (['0', 'false'].includes(val.toLowerCase())) return false;
}
return val;
}, z.coerce.boolean());
Discussion