Тип «Объект» может быть присвоен очень немногим другим типам. Вы имели в виду использовать вместо этого тип «любой»?

#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 тип.

  1. Укажите T как IUser или any тип, чтобы устранить указанную ошибку.
  2. Как комментарий @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 вместо карты.