-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Input & output types #29
Comments
For achieving the same result between valita and zod // Valita
const personSchemaInput = v.object({
name: v.string().default('john').optional(),
age: v.number(),
});
const personSchemaOutput = v.object({
name: v.string(),
age: v.number(),
});
type PersonTypeInput = v.Infer<typeof personSchemaInput>;
type PersonTypeOutput = v.Infer<typeof personSchemaOutput>;
// Zod
const personSchema = z.object({
name: z.string().default('john'),
age: z.number(),
})
type PersonTypeOutput = z.output<typeof personSchema>;
type PersonTypeInput = z.input<typeof personSchema> |
Interesting. Can you elaborate on your use-case for the described functionality? In our work the use-case for Valita has been validating (& parsing) data from external sources, like user input or 3rd party APIs, where we can't safely make assumptions about the structure of the data beforehand. Thus we have always assumed input to be |
Yes ofc. In our app we use service to call our backend, and we have multiple interface to create some types of object. |
Here another example of why we need to have two specific type. I'll take the same example as above // good input wrong output
const personSchemaInput = v.object({
name: v.string().default('john').optional(),
age: v.number(),
});
type PersonTypeInput = v.Infer<typeof personSchemaInput>;
// type PersonTypeInput = {
// name?: string | undefined;
// age: number;
// }
// wrong input good output
const personSchemaInput = v.object({
name: v.string().optional().default('john'),
age: v.number(),
});
type PersonTypeInput = v.Infer<typeof personSchemaInput>;
// type PersonTypeInput = {
// name: string;
// age: number;
// } I've found a solution without creating two object here my solution type Simplify<T> = {[KeyType in keyof T]: T[KeyType]};
type SetRequired<T, K extends keyof T> = Simplify<PersonTypeInput & Required<Pick<T, K>>>;
const personSchemaInput = v.object({
name: v.string().default('john').optional(),
age: v.number(),
});
type PersonTypeInput = v.Infer<typeof personSchemaInput>;
type PersonTypeOutput = SetRequired<v.Infer<typeof personSchemaInput>, 'name'>; |
Hello. Unfortunately I haven't had the chance to spend time on this issue. However, I'd like to quickly point out some things:
|
In my cases, input/output schemas usually differs much more than just defaults or adding .optionals. I really think manually defining two schemas is much more smart(for extending during project lifetime) & common solution. |
My usecase for this is using the input type as the type of my form so that:
This can be considered out of scope and I will continue using zod, but validation schema are also useful to transform almost know data structure and not always "unkown json" |
It seems to me that this is supported out of the box: const InputType = v.object({
name: v.string().optional(),
age: v.number(),
});
const OutputType = InputType.map(v => ({name: 'john doe', ...v}));
type InputType = v.Infer<typeof InputType>;
type OutputType = v.Infer<typeof OutputType>; You just have to apply the relevant transforms to the input type to produce the output types. |
Can the map return validation errors? |
@ArnaudBarre v.unknown().chain((x) => x === 1 ? v.ok(x) : v.err("bad value")); |
Hi there,
We really wanted to use your lib over Zod (for performance reasons), but this is the only feature that we miss here on Valita :
Is there any way to achieve this with Valita or is this feature planned ?
Regards
The text was updated successfully, but these errors were encountered: