#angular #typescript
Вопрос:
У меня довольно сложный код,который работает уже два дня, я использую оператор map от оператора rxjs, чтобы вывести значения IUser из интерфейса Iuser. Но я продолжаю получать эту ошибку «Аргумент типа» OperatorFunction<Пользователь, пустота> «не может быть присвоен параметру типа» OperatorFunction<Пользователь, пустота><Объект, пустота>». Тип «Объект» может быть присвоен очень немногим другим типам. Вы имели в виду использовать вместо этого тип «любой»? В типе «Объект» отсутствуют следующие свойства типа «Пользователь»: электронная почта, имя дисплея, токен». Заранее спасибо.
Учетная запись.сервис.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { BehaviorSubject } from 'rxjs';
import { map } from 'rxjs/operators';
import { environment } from 'src/environments/environment';
import { IUser } from '../shared/models/user';
@Injectable({
providedIn: 'root'
})
export class AccountService {
baseUrl = environment.apiUrl;
private currentUserSource = new BehaviorSubject<IUser>(null!);
currentUser$ = this.currentUserSource.asObservable();
constructor(private http: HttpClient, private router: Router) { }
login(values: any) {
return this.http.post(this.baseUrl 'account/login', values).pipe(
map((user: IUser) => {
if (user) {
localStorage.setItem('token', user.token);
this.currentUserSource.next(user)
}
})
);
}
логин.компонент.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
Пользователь.ts
export interface IUser {
email: string;
displayName: string;
token: string;
}
Комментарии:
1. Где вы подписываетесь на наблюдаемое? В любом случае,
map
всегда будет что-то возвращать (ничего значимого в вашем коде). Я подозреваю, что вы должны использоватьtap
вместо этого или потенциально заставить функцию ничего не возвращать и выполнять эту логику внутриsubscribe
непосредственно внутриlogin
.
Ответ №1:
От HttpClient
post()
,
Перегрузка № 14
post(url: string, body: any | null, options?: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
context?: HttpContext;
observe?: 'body';
params?: HttpParams | {
[param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
};
reportProgress?: boolean;
responseType?: 'json';
withCredentials?: boolean;
}): Observable<Object>;
Без указания T
для .post()
[Перегрузка #14], он вернет Observable<Object>
значение.
Перегрузка #15
post<T>(url: string, body: any | null, options?: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
context?: HttpContext;
observe?: 'body';
params?: HttpParams | {
[param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
};
reportProgress?: boolean;
responseType?: 'json';
withCredentials?: boolean;
}): Observable<T>;
Из post()
[Перегрузка #15] вы должны указать T
, например post<T>()
, чтобы он возвращал Observable<T>
значение.
Решение
Предположение: Возвращаемый ответ имеет IUser
тип.
- Укажите
T
какIUser
илиany
тип, чтобы устранить указанную ошибку. - Как комментарий @Gunnar, вы должны использовать
tap
вместоmap
того, чтобы выполнять операцию из наблюдаемого источника, не изменяя его.Использование
map
должно возвращать значение дляObservable
.
login(values: any) {
return this.http.post<IUser>(this.baseUrl 'account/login', values).pipe(
tap((user: IUser) => {
if (user) {
localStorage.setItem('token', user.token);
this.currentUserSource.next(user);
}
})
);
}
Комментарии:
1. Когда я использовал «tap», он по-прежнему возвращает ту же ошибку типа «Объект», в которой отсутствуют следующие свойства типа «Пользователь»: электронная почта, имя дисплея, токен.
2. Привет, могу я узнать, из какой части произошла ошибка?
3. Я занимаюсь этим уже несколько дней и до сих пор не избавился от ошибки. Мне все еще нужна твоя помощь. Заранее спасибо
4. Можете ли вы попытаться создать минимальный, воспроизводимый пример на StackBlitz ? Трудно отладить и решить проблему, если вы не укажете более подробную информацию о возникшей проблеме.
5. Ошибка по-прежнему связана с «Account.service.ts», когда я попытался использовать tap вместо карты.