Angular中User类实例调用方法失败及instanceof返回false问题咨询
问题原因
Angular的HttpClient.get<User>()只是TypeScript的类型断言,仅在编译阶段做类型检查,运行时并不会把API返回的JSON对象转换成User类的实例。你拿到的只是一个结构和User类匹配的普通JavaScript对象,它没有User类的原型链,自然也没有isTeacher()这类类方法,所以instanceof User会返回false。
解决方法
需要手动把API返回的JSON对象转换成User类的实例,推荐用静态工厂方法实现:
1. 修改User模型类
调整构造函数支持传入roles和courses,再添加静态方法fromJson完成JSON到实例的转换:
export class User { private readonly _id: number; private readonly _username: string; private readonly _name: string; private readonly _lastName: string; private readonly _roles: { roleName: string }[]; private readonly _courses: any[]; // 调整构造函数,新增roles和courses参数并设默认值 constructor( id: number, username: string, name: string, lastName: string, roles: { roleName: string }[] = [], courses: any[] = [] ) { this._id = id; this._username = username; this._name = name; this._lastName = lastName; this._roles = roles; this._courses = courses; } // 静态工厂方法:将JSON对象转为User实例 public static fromJson(json: any): User { return new User( json.id, json.username, json.name, json.lastName, json.roles || [], json.courses || [] ); } // 原有getter和方法保持不变 get id(): number { return this._id; } get username(): string { return this._username; } get name(): string { return this._name; } get lastName(): string { return this._lastName; } get roles(): string[] { return this._roles.map(role => role.roleName); } public isTeacher(): boolean { return this.roles.includes("ROLE_TEACHER"); } get courses(): any[] { return this._courses; } }
2. 修改CurrentUserService服务
在获取API数据后,调用User.fromJson()将JSON转换为真正的User实例:
import { Injectable } from '@angular/core'; import { HttpClient } from "@angular/common/http"; import { User } from "../../../model/user.model"; import { lastValueFrom, map } from 'rxjs'; // 引入map操作符 @Injectable({ providedIn: 'root' }) export class CurrentUserService { private _currentUser: User | undefined; constructor(private http: HttpClient) { this._currentUser = undefined; } public async getCurrentUser(): Promise<User | undefined> { if (this._currentUser === undefined) { try { this._currentUser = await this.reloadCurrentUserInfo(); // 现在可以正常调用this._currentUser.isTeacher() } catch (e) { return undefined; } } return this._currentUser; } public disposeCurrentUserInfo = (): void => { this._currentUser = undefined; } private reloadCurrentUserInfo = (): Promise<User> => { return lastValueFrom( this.http.get<any>("/currentuser").pipe( map(userJson => User.fromJson(userJson)) // 转换为User实例 ) ); } }
修改完成后,this._currentUser将是真正的User类实例,调用isTeacher()不会报错,instanceof User也会返回true。
内容的提问来源于stack exchange,提问作者diego.guerrero
相关产品推荐
相关产品推荐

