Combine报错:无法将Publishers.FlatMap返回表达式转为AnyPublisher如何解决
问题原因
错误核心是flatMap操作结束后,没有将最终的Publisher类型抹除为函数声明要求的AnyPublisher<Void, Error>。flatMap默认返回泛型的Publishers.FlatMap类型,和函数要求的返回类型不匹配,仅完成flatMap闭包内部的类型抹除不够,需要对整个链式调用结果做类型抹除。
修正方案
只需要在flatMap链式调用的末尾追加.eraseToAnyPublisher()即可,修正后的完整代码如下:
func test(ticketId: String) -> AnyPublisher<Void, Error> { campaignByTicketIdUseCase.execute(ticketId: ticketId) // 该方法返回AnyPublisher<Campaign,Error> .flatMap { (campaign) -> AnyPublisher<Void, Error> in // 原报错位置 guard let url = URL(string: "url"), validator.isParticipationValid(campaignIdentifier: campaign.identifier) else { return Result<Void, Error>.failure(HttpError()).publisher.eraseToAnyPublisher() } var request = URLRequest(url: url) request.httpMethod = "POST" return AuthSession.shared.doRequest(request: request) .tryMap({ (_: Data, response: URLResponse) -> Void in if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode != 200 { throw HttpError() } }).eraseToAnyPublisher() } .eraseToAnyPublisher() // 新增这一行完成整体类型抹除 }
补充说明
如果修改后仍有编译错误,可以做两点排查:
- 确认
AuthSession.shared.doRequest方法返回的Publisher的Failure类型是否为Error,如果是URLError等具体错误类型,需要追加.mapError { $0 as Error }再做eraseToAnyPublisher,保证上下游Failure类型一致。 - 确认flatMap闭包内所有分支的返回类型都严格为
AnyPublisher<Void, Error>,避免类型不一致的隐式报错。
内容的提问来源于stack exchange,提问作者DaVincr
相关产品推荐
相关产品推荐

