rxjs Error 抱怨类型不兼容

rxjs Error complaining about incompatible types

继续

自从在 SO 中接受一些指导以来,我已经阅读了相当多的书。我现在要解决 TS 抱怨不兼容类型的问题。我没有看到我的错误。

注意:我尝试开发代码,以便源与源之间的最大数量相同。一种技术是调用 'main' TYPE 'item'(在这种情况下......主要项目类型是 ProjRev)。
所以在这里,任何对 'item' 的引用都将指向 ProjRev 对象(当然 ProjectSvc.GetItemById 除外) 这似乎在最后一个 SO 中引起了混乱,我想我至少会澄清一下......

import { Component, OnInit,  ElementRef, ViewChild } from '@angular/core';
import { Location } from '@angular/common';
import { ChangeDetectorRef } from '@angular/core';
  import { Observable,forkJoin, combineLatest } from 'rxjs';
import { distinctUntilKeyChanged, pluck
      , switchMap ,tap} from 'rxjs/operators';
import { ActivatedRoute } from '@angular/router';

import { Project } from '../project';
import { ProjectRev} from '../project-rev';
import { ProjectService } from '../services/project.service';
import { ProjectRevService } from '../services/project-rev.service';

 

interface  VM{
    projectRev : ProjectRev;
    project : Project;
}

@Component({
  selector: 'app-project-rev-detail',
  templateUrl: './project-rev-detail.component.html',
  styleUrls: ['./project-rev-detail.component.css']
})
export class ProjectRevDetailComponent implements OnInit  {
   private projectRevId$ : Observable<string>;
   private myItem$ : Observable<ProjectRev>;
   private myProject$ : Observable<Project>;


   public vm$ : Observable<VM>   ;
   

  constructor( private projrevSvc : ProjectRevService
          , private projectSvc : ProjectService
          ,private location: Location
          ,private activatedRoute: ActivatedRoute
       ) {

       }

  ngOnInit(): void {
    this.projectRevId$ = this.activatedRoute.params.pipe(
      pluck('id')
      ,tap( id => {  console.log('pRevId',id);})
    );

    this.myItem$ = this.projectRevId$.pipe(
      tap( item => {  console.log('inside projrev pipe',item);})
      ,   switchMap( (itemId : string) => this.projrevSvc.getItemById(  itemId   ))
      , tap( item => console.log('rev retrieved',item))
    );

    this.myProject$ = this.myItem$.pipe(
      tap( (prev : ProjectRev) =>{  console.log('inside getProj pipe');})
      ,distinctUntilKeyChanged('ProjectId')
      ,switchMap((item) => this.projectSvc.getItemById(item.ProjectId))
      , tap( item => console.log('proj retrieved',item))

    );

     this.vm$   = combineLatest(

      this.myItem$,
      this.myProject$
   ).subscribe(([ projRev , project]) => {
    this.myItem$ =projRev;
    this.myProject$ = project;
});

错误信息是

   ERROR in src/app/projects/project-rev-detail/project-rev-detail.component.ts(76,5): error TS2740: Type 'Subscription' is missing the following properties from type 'Observable<VM>': _isScalar, source, operator, lift, and 114 more.
    src/app/projects/project-rev-detail/project-rev-detail.component.ts(81,9): error TS2740: Type 'ProjectRev' is missing the following properties from type 'Observable<ProjectRev>': _isScalar, source, operator, lift, and 114 more.
    src/app/projects/project-rev-detail/project-rev-detail.component.ts(82,9): error TS2740: Type 'Project' is missing the following properties from type 'Observable<Project>': _isScalar, source, operator, lift, and 114 more.

正在调用的服务函数在这里... 正如我的日志列表所证明的那样,这是有效的

 getItemById(id: string): Observable< ProjectRev> {
     console.log('inside proj rev getItemByid..');
       const url = `${this.serviceUrl}/${id}`;
       return this.http.get< ProjectRev>(url, httpOptions)
           .pipe(
             catchError(err =>
               this.handleError(`getItemById=${id}`, err))
       );

   }

我试过将 VM 接口更改为可观察的而不是可观察的。 我已经完成了更改接口和 combineLatest 参数签名的所有排列 我很确定这就是我的问题所在。

问题:当我在 ngOnit() 中初始化可观察对象时没有订阅;我从 SO answer 中获取了这个模式。应该有订阅吗? 我之前犯了不订阅的错误……这里不需要吗?

VM 模式不是必需的。它是在 SO 答案中提出的。我确实看到了将整个 UI 包装在 1 ngIf 中的优势...但前提是我可以让它工作。我可以 google 为这种模式命名吗?谁有好的例子?

考虑一下:

public count : number;
initCount(){
  this.count = "Hello!";
}

预期错误:Type 'string' is not assignable to type 'number'

那是因为我先说count是一个数字,然后给它赋了一个字符串。如何解决这个问题取决于意图。考虑到 count 的命名方式,once 可能会认为给它分配一个字符串是错误的。


关于你的代码:)

public vm$: Observable<VM>;
ngOnInit(){
  this.vm$ = someObservable.subscribe(someLambda);
}

在这里,您正在尝试将订阅分配给一个可观察对象。它与上面的错误大致相同,但 TypeScript 会尝试进行 duck-typing(查看对象属性并查看它们是否匹配)。订阅和可观察对象不重叠。

这就是您的错误消息告诉您的内容。

如何解决这个问题?最好的方式/惯用方式很难从您在这里写的内容中看出,但这是类型可能再次对齐的一种方式。

this.vm$ = combineLatest(
  this.myItem$,
  this.myProject$
).pipe(
  map(([projectRev, project]) => ({
    projectRev,
    project
  }))
);