将 fp-ts TaskEither 与右侧的 Either 链接起来
Chain fp-ts TaskEither with Either in right
我有 2 个嵌套请求的流程,其中可能有 3 个不同的结果:
- 请求之一return错误
- 用户不是匿名的,return个人资料
- 用户是匿名的,return false
两个请求都可能抛出错误,因为它实现了 TaskEither
const isAuth = ():TE.TaskEither<Error, E.Either<true, false>>
=> TE.tryCatch(() => Promise(...), E.toError)
const getProfile = ():TE.TaskEither<Error, Profile>
=> TE.tryCatch(() => Promise(...), E.toError)
第一个请求return是用户授权的布尔状态。第二个请求加载用户配置文件如果用户被授权。
在 return 中,我想得到下一个签名,Error or Either with Anonymous/Profile:
E.Either<Error, E.Either<false, Profile>>
我试过这样做:
pipe(
isAuth()
TE.chain(item => pipe(
TE.fromEither(item),
TE.mapLeft(() => Error('Anonimous')),
TE.chain(getProfile)
))
)
但是在return中,我得到E.Either<Error, Profile>
,不方便,因为我必须从Error
中手动提取Anonymous
状态。
如何解决这个问题?
不知道您是否过度简化了实际代码,但 E.Either<true, false>
仅与 boolean
同构,所以让我们坚持使用更简单的代码。
declare const isAuth: () => TE.TaskEither<Error, boolean>;
declare const getProfile: () => TE.TaskEither<Error, Profile>;
然后根据是否授权添加条件分支并包装getProfile的结果:
pipe(
isAuth(),
TE.chain(authed => authed
? pipe(getProfile(), TE.map(E.right)) // wrap the returned value of `getProfile` in `Either` inside the `TaskEither`
: TE.right(E.left(false))
)
)
此表达式的类型为 TaskEither<Error, Either<false, Profile>>
。您可能需要添加一些类型注释才能正确进行类型检查,我自己没有 运行 代码。
编辑:
您可能需要将 lambda 提取为命名函数以获得正确的类型,如下所示:
const tryGetProfile: (authed: boolean) => TE.TaskEither<Error, E.Either<false, Profile>> = authed
? pipe(getProfile(), TE.map(E.right))
: TE.right(E.left(false));
const result: TE.TaskEither<Error, E.Either<false, Profile>> = pipe(
isAuth(),
TE.chain(tryGetProfile)
);
我有 2 个嵌套请求的流程,其中可能有 3 个不同的结果:
- 请求之一return错误
- 用户不是匿名的,return个人资料
- 用户是匿名的,return false
两个请求都可能抛出错误,因为它实现了 TaskEither
const isAuth = ():TE.TaskEither<Error, E.Either<true, false>>
=> TE.tryCatch(() => Promise(...), E.toError)
const getProfile = ():TE.TaskEither<Error, Profile>
=> TE.tryCatch(() => Promise(...), E.toError)
第一个请求return是用户授权的布尔状态。第二个请求加载用户配置文件如果用户被授权。
在 return 中,我想得到下一个签名,Error or Either with Anonymous/Profile:
E.Either<Error, E.Either<false, Profile>>
我试过这样做:
pipe(
isAuth()
TE.chain(item => pipe(
TE.fromEither(item),
TE.mapLeft(() => Error('Anonimous')),
TE.chain(getProfile)
))
)
但是在return中,我得到E.Either<Error, Profile>
,不方便,因为我必须从Error
中手动提取Anonymous
状态。
如何解决这个问题?
不知道您是否过度简化了实际代码,但 E.Either<true, false>
仅与 boolean
同构,所以让我们坚持使用更简单的代码。
declare const isAuth: () => TE.TaskEither<Error, boolean>;
declare const getProfile: () => TE.TaskEither<Error, Profile>;
然后根据是否授权添加条件分支并包装getProfile的结果:
pipe(
isAuth(),
TE.chain(authed => authed
? pipe(getProfile(), TE.map(E.right)) // wrap the returned value of `getProfile` in `Either` inside the `TaskEither`
: TE.right(E.left(false))
)
)
此表达式的类型为 TaskEither<Error, Either<false, Profile>>
。您可能需要添加一些类型注释才能正确进行类型检查,我自己没有 运行 代码。
编辑:
您可能需要将 lambda 提取为命名函数以获得正确的类型,如下所示:
const tryGetProfile: (authed: boolean) => TE.TaskEither<Error, E.Either<false, Profile>> = authed
? pipe(getProfile(), TE.map(E.right))
: TE.right(E.left(false));
const result: TE.TaskEither<Error, E.Either<false, Profile>> = pipe(
isAuth(),
TE.chain(tryGetProfile)
);