valibot
valibot copied to clipboard
How to create dynamic variants with the nested schemas?
Hello!
Here is the playground MRE: https://valibot.dev/playground/?code=JYWwDg9gTgLgBAKjgQwM5wG5wGZQiOAcg2QBtgAjCGQgbgCh6BjCAO1XgCUBTVAV1IwAykwAW3EMjgBeTADoIFAFbcmMABQBvenDgBrbgE8AXPI5RgrAObqAlABp6AX1sNmbDnCExkMYEwA1ZAtkVmExCSlZDDkSELD1Qn4mJl5UQns4AG0deUUVNS1c3WTU1FRTGPIYbigydWwyVG4HYrhavChKuUsOUNT1AFEoTtbdF0ddGPzVDW1dEr4UtO7q2vqYKD4WyYWoXgEYUx5+QRFxSV2J+gBdV0YWdngAEUNWZBB-IPjwi6i4AA8ABV2gAPGqsAAm6BiAHllLNzpEAaFDJlUQA+DHqXL7U6-SKmIGOWwyDG5GJxYChDRJJZldKZHILPIIwrzFlwUoreRrOqkBpNHZtXQdaDdXo+VgDYajXbjMYLaZsuYirn0nlVYA1fnqTbbRUsvGHUzGs4RS5ta66O4MIA
Inline code:
import * as v from 'valibot';
const ResultSchema = v.object({
key: v.string(),
});
const StaticVariantSchema = v.variant('success', [
v.object({
success: v.literal(false),
error: v.instance(Error),
}),
v.object({
success: v.literal(true),
result: ResultSchema,
}),
]);
const DynamicVariantSchema = <T extends v.ObjectSchema<any, any>>(
resultSchema: T,
) =>
v.variant('success', [
v.object({
success: v.literal(false),
error: v.instance(Error),
}),
// here i'm getting error
v.object({
success: v.literal(true),
result: resultSchema,
}),
]);
const staticResult = v.parse(StaticVariantSchema, {
success: true,
result: {
key: 'string',
},
});
const dynamicResult = v.parse(DynamicVariantSchema(ResultSchema), {
success: true,
result: {
key: 'string',
},
});
console.log(staticResult, dynamicResult);
At runtime, it's working OK, but I got an error from TS:
Type 'ObjectSchema<{ readonly success: LiteralSchema<true, undefined>; readonly result: S; }, undefined>' is not assignable to type 'VariantOption<"success">'.
Type 'ObjectSchema<{ readonly success: LiteralSchema<true, undefined>; readonly result: S; }, undefined>' is not assignable to type 'ObjectSchema<Record<"success", BaseSchema<unknown, unknown, BaseIssue<unknown>>>, ErrorMessage<ObjectIssue> | undefined>'.
The types returned by '_run(...)' are incompatible between these types.
Type 'Dataset<{ [TKey in keyof WithReadonly<{ readonly success: LiteralSchema<true, undefined>; readonly result: S; }, WithQuestionMarks<{ readonly success: LiteralSchema<true, undefined>; readonly result: S; }, InferEntriesOutput<...>>>]: WithReadonly<...>[TKey]; }, ObjectIssue | InferObjectIssue<...>>' is not assignable to type 'Dataset<{ success: unknown; }, BaseIssue<unknown> | ObjectIssue>'.
Type 'TypedDataset<{ [TKey in keyof WithReadonly<{ readonly success: LiteralSchema<true, undefined>; readonly result: S; }, WithQuestionMarks<{ readonly success: LiteralSchema<true, undefined>; readonly result: S; }, InferEntriesOutput<...>>>]: WithReadonly<...>[TKey]; }, ObjectIssue | InferObjectIssue<...>>' is not assignable to type 'Dataset<{ success: unknown; }, BaseIssue<unknown> | ObjectIssue>'.
Type 'TypedDataset<{ [TKey in keyof WithReadonly<{ readonly success: LiteralSchema<true, undefined>; readonly result: S; }, WithQuestionMarks<{ readonly success: LiteralSchema<true, undefined>; readonly result: S; }, InferEntriesOutput<...>>>]: WithReadonly<...>[TKey]; }, ObjectIssue | InferObjectIssue<...>>' is not assignable to type 'TypedDataset<{ success: unknown; }, BaseIssue<unknown> | ObjectIssue>'.
Property 'success' is missing in type '{ [TKey in keyof WithReadonly<{ readonly success: LiteralSchema<true, undefined>; readonly result: S; }, WithQuestionMarks<{ readonly success: LiteralSchema<true, undefined>; readonly result: S; }, InferEntriesOutput<...>>>]: WithReadonly<...>[TKey]; }' but required in type '{ success: unknown; }'.ts(2322)
Am I doing something wrong with the generics, or is it a bug?