Generic types
Closed this issue · 3 comments
TmLev commented
Is it possible to define generic type as one of the variants?
My attempt:
const LoadState = makeTaggedUnion({
Unstarted: none,
Loading: (percentLoaded: number) => percentLoaded,
Loaded: <T>(response: T) => response,
Error: (error: Error) => error,
});
type LoadState<T> = MemberType<typeof LoadState> // Doesn't really work since `LoadState` is not generic.
suchipi commented
Due to limitations in TypeScript, you can't really do generics with these values, since they're not functions or classes. But, you can do something pretty close by using a function to create tagged unions, like so:
function makeMaybe<T>() {
return makeTaggedUnion({
Some: (data: T) => ({ data }),
None: none,
});
}
const Maybe_String = makeMaybe<string>();
const Maybe_Number = makeMaybe<number>();
const data1 = Maybe_String.Some("hi");
const data2 = Maybe_Number.Some(456);
data1.match({
Some: ({ data }) => data, // data is string here
None: () => null,
});
data2.match({
Some: ({ data }) => data, // data is number here
None: () => null,
});
It's not as nice, but it works.
TmLev commented
Thanks!
Unfortunately, this approach cannot be used in context where, for example, type of Maybe.Some
is controlled by caller, since it would require creating required type on each invocation, but it works for simple cases.
suchipi commented
Here's a solution that allows Maybe.Some
to still be controlled by the caller: #15 (comment)