Union with all literals from specific type #1234
-
|
I want to create a schema to validate union type, e.g.: type TestType = 'woof' | 'bark
const schema = v.union([
v.literal<TestType>('woof'),
v.literal<TestType>('bark')
])The problem is, this check will not handle cases when a new value is added to Ideally, I'd like to have an exclusive array of unions that I can use to build the argument for |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
|
Hi @Perdolique! I'm Dosu and I’m helping the valibot team. Valibot doesn't support passing a TypeScript union type directly to v.union or auto-generating a union schema from a type, due to TypeScript's type erasure at runtime. The recommended DRY approach is to use a single runtime array (as const) or an enum/object as your source of truth, and derive both your TypeScript type and your schema from it. This keeps everything in sync and avoids duplication or omissions. For example, using a const array and picklist: const testTypes = ['woof', 'bark'] as const;
type TestType = typeof testTypes[number];
const schema = v.picklist(testTypes);Or, if you prefer enums: const TestEnum = { Woof: 'woof', Bark: 'bark' } as const;
type TestType = (typeof TestEnum)[keyof typeof TestEnum];
const schema = v.enum(TestEnum);This way, adding or removing values only requires changing the array or enum, and both your type and schema will always match. This also prevents duplicates and ensures all values are covered, since the runtime array or enum is the single source of truth. More details and examples are in the Valibot picklist and enum docs. If you need dynamic validation (e.g., the allowed values change at runtime), you can recreate the schema when the source changes, or use a custom/check validator as described here. To reply, just mention @dosu. How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other |
Beta Was this translation helpful? Give feedback.
This works too but it is a bit more complicated. Feel free to try it out in our playground.