Reputation: 8587
I would like to use a custom union, or generally a custom type in io-ts.
I receive an error in this like
T.array(T.type(MyUnion))
Could you please tell me what is the right way to achieve this?
import * as T from 'io-ts';
import * as E from 'fp-ts/Either';
import { pipe } from 'fp-ts/lib/function';
console.clear();
type MyUnion = 'item-a' | 'item-b' | 'item-c';
const test1 = T.type({
data: T.array(T.string),
});
pipe(test1.decode({ data: ['hello'] }), E.fold(console.error, console.log)); // OK
const test2 = T.type({
data: T.array(T.type(MyUnion)), // ERROR
});
pipe(test2.decode({ data: ['hello'] }), E.fold(console.error, console.log));
Upvotes: 0
Views: 277
Reputation: 26324
You would need to define a variable named MyUnion
so you can use at runtime first:
const MyUnion = T.union([T.literal("item-a"), T.literal("item-b"), T.literal("item-c")]);
but it's quite redundant to use this again:
type MyUnion = 'item-a' | 'item-b' | 'item-c';
Fortunately, io-ts has a built-in type TypeOf
that gets the type of an io-ts type as a TS type, which removes the redundancy:
type MyUnion = T.TypeOf<typeof MyUnion>;
// ^? 'item-a' | 'item-b' | 'item-c'
Then you'll be able to use MyUnion
as both an io-ts type (at runtime), and a TS type (at compile-time):
const test2 = T.type({
data: T.array(MyUnion), // ok
});
Upvotes: 0