2016-11-28 1 views
1

У меня есть метод, который возвращает либо объект, либо массив из одних и тех же объектов на основе URL-адреса запроса. логика проста;возвращать несколько типов наблюдаемых в Typcript

myservice.service.ts:

private _url_User = "https://api.github.com/users/dummyuser"; 
constructor(private _http: Http){} 

getUsers(followers?: boolean): Observable<User | User[]>{ 
     this._url_User += followers?"/followers":"";//if followers equals true edit url, this returns array of same user object 
     return this._http.get(this._url_User).map(res=>res.json()); 
    } 

mycomponent.component.ts:

import { Component,OnInit } from '@angular/core'; 
import {Auth} from '../../services/auth.service'; 
import {CommentService} from '../../services/comment.service'; 
import {User} from '../../infrastructure/user'; 

@Component({ 
    moduleId:module.id, 
    selector: 'app-comment', 
    templateUrl: '../../templates/comment.component.html' 
}) 

export class CommentComponent implements OnInit{ 
    user:User; 
    followers:User[]; 
    constructor(private auth: Auth, private commentService: CommentService){ 
    } 
    ngOnInit(){ 
     this.commentService.getUsers().subscribe(d=>{ this.user=d[0]; console.log(this.user.email)}); 
     this.commentService.getUsers(true).subscribe(d=>{this.followers=d; console.log(this.followers[0].email)}); 
    } 
} 

и вот сообщение об ошибке, я не мог ручка; enter image description here

ответ

4

В общем, то, что я предлагаю делать, фактически разделяет это на два метода, а не на использование булевого флага. Это будет проще и понятнее, а также решит проблему с типизацией здесь бесплатно.

Если вы действительно не хотите этого делать, то вам нужно добавить function overload к вашему методу. С их помощью вы можете указать TypeScript, что эта функция всегда возвращает одного пользователя с установленным флагом флагом или многими пользователями, если для флага установлено значение true, и вы получите поведение, которое вы ищете.

Перегрузка для этой функции будет выглядеть примерно так:

getUsers(): Observable<User>; 
getUsers(followers: false): Observable<User>; 
getUsers(followers: true): Observable<User[]>; 
getUsers(followers?: boolean): Observable<User | User[]>{ 
    this._url_User += followers?"/followers":""; 
    return this._http.get(this._url_User).map(res=>res.json()); 
} 

Я положил вместе a working example на детской площадке, если вы хотите, чтобы увидеть то, что все это выглядит.

Обратите внимание, что это сохраняет потенциальную двусмысленность там, где она все еще существует. То есть если вы вызываете getUsers с булевым и во время компиляции, то TypeScript не знает, будет ли это true или false, он все равно вернет Observable<User | User[]>. Вам нужно будет использовать утверждения типа или охранник типа, чтобы получить правильный тип - ознакомьтесь с разделом Type Guards and Differentiating Types в справочнике, если вы не знакомы с этим материалом.

+0

Рабочий пример, похоже, не компилируется: «Тип« строка »не может быть присвоен типу 'string []'." – spottedmahn

+0

@spottedmahn это намеренно - обратите внимание на комментарии в коде, вызывающем эту функцию внизу, которые разделяют примеры на «Все действительные» (которые выполняются и должны компилироваться) и «Недействительные» (различные примеры, которые этого не делают, и не должны) –

+0

О, извините, я не читал достаточно близко. Я только что открыл пример и нажал пробег! Спасибо за разъяснения! – spottedmahn

Смежные вопросы