Codecs composition: how to nest one into another? #5270
-
|
Using Zod I have Question: how to define codec of Here is sample class PublicKey {
#algorithm: string;
#payload: string;
public static parse(str: string): PublicKey {
const [alg, payload] = str.split("#");
return new PublicKey(alg, payload);
}
public constructor(alg: string, payload: string) {
this.#algorithm = alg;
this.#payload = payload;
}
public toString(): string {
return `${this.#algorithm}#${this.#payload}`;
}
}
const PublicKeyCodec = z.codec(
z.string(),
z.instanceof(PublicKey),
{
encode: (x) => x.toString(),
decode: (x) => PublicKey.parse(x),
},
);This works as expected. However, this does not work: const PublicKeySetCodec = z.codec(
z.array(PublicKeyCodec),
z.set(PublicKeyCodec),
{
// Zod expects: (value: Set<string>) => PublicKey[]
encode: (x) => [...x],
// Zod expects: (value: PublicKey[]) => Set<string>
decode: (x) => new Set(x),
},
);As a workaround, I can duplicate the contents of const PublicKeySetCodec2 = z.codec(
z.array(z.string()),
z.set(z.instanceof(PublicKey)),
{
encode: (x) => [...x].map(y => y.toString()),
decode: (x) => new Set(x.map(y => PublicKey.parse(y))),
},
);Is there a way of doing so while treating |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
|
Hi @0x009922! I'm Dosu and I’m helping the zod team. I'm a bot trained on Zod's codebase and issues. In Zod v4.1.11, codecs are fully composable in arrays and objects, but there isn't a built-in way to automatically compose encode/decode logic for container types like To avoid duplicating logic, you can define reusable encode/decode helpers outside of Zod and use them in your container codec. For example: // Reuse PublicKeyCodec's encode/decode
const encodePublicKey = PublicKeyCodec.encode;
const decodePublicKey = PublicKeyCodec.decode;
const PublicKeySetCodec = z.codec(
z.array(z.string()),
z.set(z.instanceof(PublicKey)),
{
encode: (set) => [...set].map(encodePublicKey),
decode: (arr) => new Set(arr.map(decodePublicKey)),
}
);This way, you treat If this answers your question, please close the issue! To reply, just mention @dosu. How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other |
Beta Was this translation helpful? Give feedback.
Hello! I'm not sure I will answer your question completely, but I saw your discussion as I'm taking a look at nested codecs as well.
Your last suggestion caught my attention because I think here is a way to get the input and output schemas that you would like to access. As this is not directly documented, I am not sure they are considered "public", but they do exist.
Based on your last code snippet, this seems to work (at least at the type level, I didn't test the runtime)
Feel free to discard my comment if I'm off topic, I just thought this might help 🙂