Angular 12 - Error : No overload matches this call. Overload 1 of 5

Angular 12 - Error : No overload matches this call. Overload 1 of 5

以下是我的代码:

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { BehaviorSubject } from 'rxjs';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  isAuth$ = new BehaviorSubject<boolean>(false);
  token!: string ; 
  userId!: string;

  constructor(private router: Router,
    private http: HttpClient) { }


  createNewUser(email: string, password: string) {
    return new Promise<void>((resolve, reject) => {
      this.http.post(
        'http://localhost:3000/api/auth/signup',
        { email: email, password: password })
        .subscribe(
          () => {
            this.login(email, password).then(
              () => {
                resolve();
              }
            ).catch(
              (error) => {
                reject(error);
              }
            );
          },
          (error) => {
            reject(error);
          }
        );
    });
  }

  login(email: string, password: string) {
    return new Promise<void>((resolve, reject) => {
      this.http.post(
        'http://localhost:3000/api/auth/login',
        { email: email, password: password })
        .subscribe(
          (authData: { token: string, userId: string }) => {  //====> Error 
            this.token = authData.token;
            this.userId = authData.userId;
            this.isAuth$.next(true);
            resolve();
          },
          (error) => {
            reject(error);
          }
        );
    });
  }

  logout() {
    this.isAuth$.next(false);
    this.userId = null!;
    this.token = null!;
  }
}

错误描述:

No overload matches this call. Overload 1 of 5, '(next: null, error: (error: any) => void, complete?: () => void): Subscription', gave the following error. Argument of type '(authData: { token: string; userId: string;}) => void' is not assignable to parameter of type 'null'.
Overload 2 of 5, '(next?: (value: Object) => void, error?: (error: any) => void, complete?: () => void): Subscription', gave the following error. Argument of type '(authData: { token: string; userId: string;}) => void' is not assignable to parameter of type '(value: Object) => void'. Types of parameters 'authData' and 'value' are incompatible. The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? Type 'Object' is missing the following properties from type '{ token: string; userId: string; }': token, userId

The following is my code

Error description

您必须指定预期为 this.http.post 接收的响应数据类型。

解决方案 1:指定为 { token: string, userId: string } 类型

login(email: string, password: string) {
    return new Promise<void>((resolve, reject) => {
      this.http.post<{ token: string, userId: string }>(
        'http://localhost:3000/api/auth/login',
        { email: email, password: password })
        .subscribe(
          (authData: { token: string, userId: string }) => { 
            this.token = authData.token;
            this.userId = authData.userId;
            this.isAuth$.next(true);
            resolve();
          },
          (error) => {
            reject(error);
          }
        );
    });
  }

解决方案 2:指定为 any 类型

login(email: string, password: string) {
    return new Promise<void>((resolve, reject) => {
      this.http.post<any>(
        'http://localhost:3000/api/auth/login',
        { email: email, password: password })
        .subscribe(
          (authData: { token: string, userId: string }) => { 
            this.token = authData.token;
            this.userId = authData.userId;
            this.isAuth$.next(true);
            resolve();
          },
          (error) => {
            reject(error);
          }
        );
    });
  }

您可以将 this.http.post 函数的通用类型更改为 { token: string, userId: string },如下所示:

this.http.post<{ token: string, userId: string }>(......);

但是,我认为在您的情况下最好直接使用 Observable 而无需 promise,并且无需在您的函数中进行订阅。

您可以像下面这样实现:

  login(email: string, password: string): Observable<void> {
    return this.http
      .post<{ token: string; userId: string }>(
        "http://localhost:3000/api/auth/login",
        {
          email: email,
          password: password,
        }
      )
      .pipe(
        map((authData) => {
          this.token = authData.token;
          this.userId = authData.userId;
          this.isAuth$.next(true);
        })
      );
  }