假设我有以下类型:
type ValidatedInput = Readonly<{
id: string
}>
type GetStructures = (id: string) => TaskEither<ServiceError, ReadonlyArray<SomeStructure>>
type GetOtherStructures = (ids: ReadonlyArray<string>) => TaskEither<ServiceError, ReadonlyArray<SomeOtherStructure>>
type LookupThings = (initialInput: ReadonlyArray<SomeStructure>, additionalInput: ReadonlyArray<SomeOtherStructure>) => TaskEither<ServiceError, ReadonlyArray<Option<ResponseType>>>
export type Deps = Readonly<{
getStructures: GetStructures
getOtherStructures: GetOtherStructures
lookupThings: LookupThings
}>
export type Ctx<T> = ReaderTaskEither<Deps, Error, T>
以及以下错误处理助手:
type Code = 'INVALID_ENTITY' | 'INVALID_API_KEY'
export const fromCode = (code: Code): Error => ({
tag: 'validation',
code
})
然后我创建一个像这样的函数:
const constructFullData = (input: ValidatedInput): Ctx<ReadonlyArray<Option<ResponseType>>> => (
(deps: Deps): TE.TaskEither<Error, ReadonlyArray<Option<ResponseType>>> => (
pipe(
deps.getStructures(input.id),
TE.map((structs) => pipe(
deps.getOtherStructures([structs[0].higherOrderId]),
TE.chain(otherStructs => pipe(
deps.lookupThings(structs, otherStructs),
TE.chain(results => {
if (results.filter(isNone).length !== results.length) {
return TE.left(fromCode('INVALID_ENTITY')) // I'm not sure what a better way to filter this is. Ideally the return type of this function wouldn't have an Option in it
} else {
return TE.right(results)
}
})
))
)),
TE.flatten
)
)
)
这一切都编译得很好,但我真正想要的是返回一个没有过滤掉的数组,如果没有则引发适当的错误!
天真的方法是将 Right 路径的返回更改为:
return TE.right(results.map(u => u.value))
但这不会编译,抛出以下错误:
Property 'value' does not exist on type 'None'.
64 return TE.right(usagesWithDrones.map(u => u.value))
如何应用这种过滤?