A
arktype•3w ago
winterbolt

Is there an equivalent to Zod's `coerce`?

Hello, I am trying to convert the following Zod schema to ArkType:
const Params = z.object({
sort: z
.union([
z.literal("name"),
z.literal("newest"),
z.literal("oldest"),
z.literal("modified"),
])
.default("newest"),
limit: z.coerce.number().int().min(1).max(10).default(10),
page: z.coerce.number().int().min(0).default(0),
});
const Params = z.object({
sort: z
.union([
z.literal("name"),
z.literal("newest"),
z.literal("oldest"),
z.literal("modified"),
])
.default("newest"),
limit: z.coerce.number().int().min(1).max(10).default(10),
page: z.coerce.number().int().min(0).default(0),
});
So far, I have this:
const Params = type({
sort: type("'name' | 'newest' | 'oldest' | 'modified'").default("newest"),
limit: type("string.integer")
.pipe(Number)
.and("1 <= number.integer <= 10")
.default(10),
page: type("string.integer")
.pipe(Number)
.and("number.integer >= 0")
.default(0),
});
const Params = type({
sort: type("'name' | 'newest' | 'oldest' | 'modified'").default("newest"),
limit: type("string.integer")
.pipe(Number)
.and("1 <= number.integer <= 10")
.default(10),
page: type("string.integer")
.pipe(Number)
.and("number.integer >= 0")
.default(0),
});
But I get errors when using default for limit and page saying: Argument of type 'number' is not assignable to parameter of type '() => never'.ts(2345) and also the type when hovering over it doesn't seem right:
const Params: Type<{
sort: Default<"name" | "newest" | "oldest" | "modified", "newest">;
limit: Default<(In: never) => Out<number>, never>;
page: Default<(In: never) => Out<number>, never>;
}, {}>
const Params: Type<{
sort: Default<"name" | "newest" | "oldest" | "modified", "newest">;
limit: Default<(In: never) => Out<number>, never>;
page: Default<(In: never) => Out<number>, never>;
}, {}>
I assume it's not inferring the types correctly or am I doing something wrong? Is this a right way to emulate Zod's coerce?
3 Replies
TizzySaurus
TizzySaurus•3w ago
I'd guess maybe something like
type("1 <= string.integer.parse <= 10").default(0)
type("1 <= string.integer.parse <= 10").default(0)
Maybe with the default as "0" instead of 0
winterbolt
winterboltOP•3w ago
Oh, close! Your tip + the error messages guided me to this:
const Params = type({
sort: type("'name' | 'newest' | 'oldest' | 'modified'").default("newest"),
limit: type("string.integer.parse").to("1 <= number <= 10").default("1"),
page: type("string.integer.parse").to("number >= 0").default("0"),
});
const Params = type({
sort: type("'name' | 'newest' | 'oldest' | 'modified'").default("newest"),
limit: type("string.integer.parse").to("1 <= number <= 10").default("1"),
page: type("string.integer.parse").to("number >= 0").default("0"),
});
It's annoying that I have to use "0" instead of just 0, but it works! 😄 Thanks!
TizzySaurus
TizzySaurus•3w ago
Ah, nice!

Did you find this page helpful?