Angular中EventEmitter作为Observable使用时出现TS2740类型错误的原因排查
解决EventEmitter与Observable类型不匹配的TS2740错误
问题根源
你碰到的这个TS2740错误,本质是类型赋值不兼容:
ColumnFilterComponent里的filterChange$确实是EventEmitter<ColumnFilterEvent>类型,但一旦你对它调用RxJS的pipe()操作符,返回的结果就不再是EventEmitter了——它会被转换成Observable<ColumnFilterEvent>。- 而你偏偏把这个Observable类型的结果,赋值给了声明为
EventEmitter<ColumnFilterEvent>的变量tbFilter$,TypeScript当然会报错,因为Observable没有EventEmitter特有的emit、closed、observers这些属性。
至于MatPaginator的page能直接用,是因为你没对它做pipe()处理,它的类型还是原生的EventEmitter<PageEvent>,和你声明的变量类型一致,所以没触发错误。
修复方案
只需要修正tbFilter$的类型声明,把它改成Observable<ColumnFilterEvent>就可以了。另外建议统一把所有流的类型都对齐成Observable,这更符合RxJS的最佳实践:
// Filtering - 修正类型为Observable const tbFilter$: Observable<ColumnFilterEvent> = this.tbFilter.filterChange$.pipe( tap((event: ColumnFilterEvent) => console.log(event)) );
更进一步,你可以把page$也转换成Observable类型(虽然EventEmitter本身是Observable的子类,merge也能处理,但统一类型会让代码更清晰):
// Sorting const sort$: Observable<Sort> = this.sort.sortChange.pipe( tap(() => { this.paginator.pageIndex = 0; }) ); // Paging - 转换成Observable,统一类型 const page$: Observable<PageEvent> = this.paginator.page.asObservable(); // Filtering const tbFilter$: Observable<ColumnFilterEvent> = this.tbFilter.filterChange$.pipe( tap((event: ColumnFilterEvent) => console.log(event)) ); merge(sort$, page$, tbFilter$) .pipe(tap(() => this.refresh())) .subscribe();
这样不仅解决了类型错误,代码的可读性和一致性也会更好,避免后续再出现类似的类型混淆问题。
内容的提问来源于stack exchange,提问作者Kees de Bruin
相关产品推荐
相关产品推荐

