zod.coerce()
stringに対して使っている例
tsconst schema = z.coerce.string();
schema.parse("tuna"); // => "tuna"
schema.parse(12); // => "12"
schema.parse(true); // => "true"
tsz.preprocess(String, z.string())
coerce()
のほうがchainしやすくて良さそうね

と、思ったがpreprocessの方でもzod.pipeを併用したら同じことが出来る
どのprimitive型に対しても使える
tsz.coerce.string(); // String(input)
z.coerce.number(); // Number(input)
z.coerce.boolean(); // Boolean(input)
z.coerce.bigint(); // BigInt(input)
z.coerce.date(); // new Date(input)
numberに対して使って、number以外が来た時はちゃんとerrorになる
tsz.coerce.number().parse('hoge') // errror