Can anyone help me understand how to work with union and generic types by re-implementing something similar to Either
or Option
? Here is the code I have:
type Error = {
readonly _tag: 'error';
status: number;
statusText: string;
};
type Success<T> = {
readonly _tag: 'success';
response: T;
};
type PossibleError<T> = Error | Success<T>;
const isSuccessful = <T>(p: PossibleError<T>) => p._tag === 'success';
function fold<T>(
onSuccess: (e: Success<T>) => void,
onError: (a: Error) => void
): (pe: PossibleError<T>) => void {
return pe => (isSuccessful(pe) ? onSuccess(pe.response) : onError(pe));
}
Unfortunately, I encountered the following error:
error TS2339: Property 'response' does not exist on type 'PossibleError<T>'.
Property 'response' does not exist on type 'Error'.
return pe => (isSuccessful(pe) ? onSuccess(pe.response) : onError(pe));
~~~~~~~~
error TS2345: Argument of type 'PossibleError<T>' is not assignable to parameter of type 'Error'.
Type 'Success<T>' is missing the following properties from type 'Error': status, statusText
return pe => (isSuccessful(pe) ? onSuccess(pe.response) : onError(pe));
I am struggling to make TypeScript understand the type of pe
based on my isSuccessful
function. How can I access the right parts of my data structure to work with them effectively?
I reviewed the fp-ts
implementation of either and noticed they use .left
and .right
, so I'm not sure what is different in my code.