💎

【Zod】string型の"true", "false"をboolean型のtrue, falseに変換する

2025/02/15に公開

はじめに

何がしたかったか

文字列として存在する"true""false"をzodでbooleanにしてtruefalseに直そうとしました。

全部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