2016-10-25 20 views
7

Mam aplikację Angular2, która ma usługę, która pobiera listę elementów. Istnieje również metoda pobierania bardziej szczegółowych informacji dla każdego elementu na liście. Moja obecna konfiguracja jest:Prawidłowe wnioskowanie typów podczas łączenia obserwatorów

// 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()); 
    } 
} 

To faktycznie działa dokładnie tak, jak trzeba go chociaż tablica < => obserwowalne wydaje się trochę funky, ale kończy się dając mi zaobserwować tablicy elementów ze wszystkimi informacji o pozycji.

Problem polega na linii return this.fetchItems() zawsze dotrzesz:

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[]>'. 

jestem na kawałku straty od fetchItems nie zwróci Observable i zmieniając go do Observable<any> daje takie same błąd. Jeśli po prostu zmienię go na any, ale nie otrzymuję żadnych raportów o błędach.

Czy istnieje lepszy typ do użycia dla fetchItems?

Odpowiedz

1

jestem podejrzliwy, że to może mieć coś wspólnego z toArray() która zwraca Observable<T[]>.

W twoim przypadku, w którym można zdefiniować fetchItems(): Observable<Item[]> to sprawia toArray() wrócić Observable<Observable<Item[]>[]> tak dlatego, że zgłasza błąd nawet z Observable<any>.

Btw próbowałem symulować sytuację z klasami tylko pozornie i skompilowany bez błędów (maszynopis 2.0.3), ale może ja gdzieś popełnił błąd i jej nie identyczne (?):

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()); 
    } 
} 
0

spróbuj dodać zwrócone informacje typu do swoich map i zmienić swoje adnotacje tablicy:

  1. Zamiast Item[] użyć Array<Item>.
  2. fetchData(item: Item): ItemData i .map((item: Item): ItemData => this.itemService.fetchData(item))
15

Kiedy prowadził do tej samej kwestii, powodem było to, że zapomniałem importować Response klasa:

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

nadzieję, że pomaga kogoś.

+0

Fsck! to mi się właśnie przydarzyło i stało się tak, ponieważ zbytnio zaufałem WebStormowi - WebStorm nie dodał go automatycznie, a ja nawet nie sprawdziłem, czy ... :-) –

+1

@BoazRymland yep, to dziwne, że nie robi tego ". t nawet ostrzega przed używaniem klasy, która nie jest importowana – yefrem

Powiązane problemy