链接可观察量时正确推断类型

Exp*_*lls 7 rxjs typescript angular

我有一个Angular2应用程序,它有一个获取项目列表的服务.还有一种方法可以为列表中的每个项目获取更多特定信息.我目前的设置是:

// service for item list
class ItemsService {
  fetchItems(): Observable<Item[]> {
    return this.http.get(url).map((res: Response) => res.json());
  }
  fetchItemsWithData(): Observable<Item[]> {
    return this.fetchItems()
    .flatMap((items: Observable<Item[]>) => items)
    .map((item: Item) => this.itemService.fetchData(item))
    .flatMap((items: Observable<Item[]>) => items)
    .toArray();
  }
}

// service for individual items
class ItemService {
  fetchData(item: Item) {
    return this.http.get(`${url}/${item.id}`)
    .map((res: Response) => res.json());
  }
}
Run Code Online (Sandbox Code Playgroud)

这实际上就像我需要它一样,即使数组<=> observable看起来有点时髦,但它最终给了我一个包含所有项目信息的项目数组的可观察性.

问题是,return this.fetchItems()我总是得到:

The type argument for type parameter 'T' cannot be inferred from the usage.
Consider specifying the type arguments explicitly.
  Type argument candidate 'Item[]' is not a valid type argument because it is not a
  supertype of candidate 'Observable<Item[]>'.
    Property 'length' is missing in type 'Observable<Item[]>'.
Run Code Online (Sandbox Code Playgroud)

我有点不知所措,因为fetchItems返回Observable并更改它会Observable<any>产生同样的错误.如果我只是将其更改为any虽然我根本没有收到任何错误报告.

有更好的类型可供使用fetchItems吗?

yef*_*rem 15

当我遇到同样的问题时,原因是我忘了导入Response课程:

import { Http, Response } from '@angular/http';

希望它可以帮助某人.


mar*_*tin 1

toArray()我怀疑这可能与which returns有关Observable<T[]>

在您定义它的情况下,fetchItems(): Observable<Item[]>它会toArray()返回Observable<Observable<Item[]>[]>,这就是为什么即使使用Observable<any>.

顺便说一句,我尝试仅使用模拟类来模拟您的情况,并且编译时没有错误(TypeScript 2.0.3),但也许我在某个地方犯了错误并且它不完全相同(?):

class Observable<T> {
    map(_): Observable<T> { return new Observable<T>() }
    flatMap(_): Observable<T> { return new Observable<T>() }
    toArray(): Observable<T[]> { return new Observable<T[]>() }
}
class Item { }
class Response {
    json() { }
}
class HTTP {
    get(_) { return new Observable() }
}


class ItemsService {
    itemService = new ItemService();
    http = new HTTP();

    fetchItems(): Observable<Item[]> {
        return this.http.get('url').map((res: Response) => res.json());
    }

    fetchItemsWithData(): Observable<Item[]> {
        return this.fetchItems()
            .flatMap((items: Observable<Item[]>) => items)
            .map((item: Item) => this.itemService.fetchData(item))
            .flatMap((items: Observable<Item[]>) => items)
            .toArray();
    }
}

// service for individual items
class ItemService {
    http = new HTTP();

    fetchData(item: Item) {
        return this.http.get('url')
            .map((res: Response) => res.json());
    }
}
Run Code Online (Sandbox Code Playgroud)