Angular从Observable对象数组返回Observable对象报ts2322错误如何解决?
报错根因
TypeScript 报错的核心原因是 Array.find() 方法的返回值天然是 T | undefined 类型——如果数组中没有匹配到符合条件的元素,就会返回 undefined,和你声明的 getById 方法返回值 Observable<Todo> 要求的 Todo 类型不匹配。
你之前修改返回类型为 Observable<Todo | undefined> 仍然报错,大概率是调用这个方法的上游代码还在限定接收 Observable<Todo> 类型,没有同步修改类型兼容。
解决方案
下面给你几种可选的实现方式,根据你的业务场景选择即可:
方案1:兼容undefined返回(推荐)
如果业务允许找不到对应id的todo场景存在,直接同步修改方法返回类型,并且调整所有调用处的类型即可:
// 修改service中的方法定义 public getById(id: string): Observable<Todo | undefined> { return this.todos$.pipe( map(todos => todos.find(todo => todo._id === id)) ); } // 调用处也要同步处理undefined的情况,比如: this.todoService.getById('xxx').subscribe(todo => { if (todo) { // 处理正常todo逻辑 } else { // 处理todo不存在的逻辑 } })
方案2:非空断言(仅业务确定一定能找到时使用)
如果你在业务逻辑中能100%保证调用getById时,对应id的todo一定存在于数组中,可以直接用非空断言运算符!告诉TypeScript这个返回值不可能为undefined:
public getById(id: string): Observable<Todo> { return this.todos$.pipe( map(todos => todos.find(todo => todo._id === id)!) ); }
注意:这个方案要谨慎使用,如果实际运行时出现找不到的情况,后续逻辑会拿到undefined值引发运行时报错。
方案3:找不到时抛出错误/返回默认值
如果你需要保证流只会发射Todo类型,也可以在找不到时主动抛出错误,或者返回一个预设的默认Todo对象:
import { map, catchError } from 'rxjs/operators'; import { of } from 'rxjs'; public getById(id: string): Observable<Todo> { return this.todos$.pipe( map(todos => { const target = todos.find(todo => todo._id === id); if (!target) throw new Error(`Todo with id ${id} not found`); return target; }), catchError(err => { // 这里也可以自定义错误处理,或者返回默认Todo console.error(err); // 示例默认Todo return of({ _id: 'default', title: '未找到任务', date: new Date(), isDone: false, importance: 0 } as Todo) }) ); }
方案4:过滤掉undefined值
如果你希望流仅在找到对应todo时才发射值,找不到就不发射,可以加个filter运算符:
import { map, filter } from 'rxjs/operators'; public getById(id: string): Observable<Todo> { return this.todos$.pipe( map(todos => todos.find(todo => todo._id === id)), filter((todo): todo is Todo => !!todo) // 类型守卫过滤掉undefined ); }
内容的提问来源于stack exchange,提问作者Uri Gross
相关产品推荐
相关产品推荐

