iOS Combine Swift类型错误求助:可选路径返回userId问题
Combine类型不匹配错误解决方法
错误原因
你的代码里Just(userId).eraseToAnyPublisher()返回的是AnyPublisher<Int?, Never>,但flatMap闭包要求返回的是AnyPublisher<Int?, Error>——Never和Error是不兼容的失败类型,导致类型转换报错。
解决办法
只需要把Just的失败类型强制转换成Error即可,有几种简单的实现方式:
方法1:使用setFailureType(最简洁)
直接给Just添加setFailureType(to: Error.self),把Never类型转换成Error:
func save(_ user: User, roles: [Role]?) -> AnyPublisher<Int?, Error> { return repository.save(user) .flatMap { userId -> AnyPublisher<Int?, Error> in if let roles = roles { return repository.updateByUserId(userId, roles: roles) .map { _ in userId } .eraseToAnyPublisher() } else { return Just(userId) .setFailureType(to: Error.self) // 关键修改 .eraseToAnyPublisher() } } .eraseToAnyPublisher() }
方法2:用Future替代Just
Future可以直接指定失败类型为Error,手动返回成功结果:
// 替换else分支的代码 return Future { promise in promise(.success(userId)) } .eraseToAnyPublisher()
方法3:用Result.Publisher
利用Result.success生成的Publisher,其失败类型默认是Error:
// 替换else分支的代码 return Result.success(userId).publisher .eraseToAnyPublisher()
原理说明
Combine要求flatMap的所有分支返回的Publisher必须拥有完全一致的Output和Failure类型。repository.updateByUserId返回的是带Error失败类型的Publisher,而Just默认的失败类型是Never(表示永远不会失败),所以必须把Never转换成Error,让两个分支的类型统一,编译器才会通过。
内容的提问来源于stack exchange,提问作者Source
相关产品推荐
相关产品推荐

