Vue2转Vue3:Axios+Promise代码迁移TypeScript及优化咨询
问题解答
1. 消除TypeScript报错
针对代码里的类型问题,逐个修正如下:
核心类型定义修正
token初始值为null,但原类型string不允许赋值null,需改为联合类型:token: string | null = nulltokenInProcess会被赋值为Promise、布尔值或undefined,原boolean类型不匹配,更新为:tokenInProcess: Promise<boolean> | boolean | undefined = false
方法逻辑与类型适配
- 明确
auth()方法的返回值类型为Promise<boolean>,避免TS自动推断错误:async auth(): Promise<boolean> { // 后续逻辑 } get方法的params参数原定义要求必须包含SESSION_TOKEN,但实际会被覆盖,且this.token可能为null,调整参数类型为可选:public get(url: string, params?: { SESSION_TOKEN?: string }) { // 后续逻辑 }- 移除
auth方法里多余的外层Promise包装,直接返回认证请求的Promise,避免类型嵌套混乱。
修正后的基础代码片段
import axiosInstance from './axiosInstance' export default new (class bmRequest { username = 'user' password = '123456' token: string | null = null tokenInProcess: Promise<boolean> | boolean | undefined = false async auth(): Promise<boolean> { if (this.tokenInProcess instanceof Promise) { return this.tokenInProcess } if (this.token) { return true } this.tokenInProcess = axiosInstance .post('/auth', { login: this.username, password: this.password, }) .then((response) => { if (response.status === 200) { this.token = response.data.SESSION_TOKEN this.tokenInProcess = undefined return true } else { this.tokenInProcess = false return false } }) .catch(() => { this.tokenInProcess = false return false }) return this.tokenInProcess } public async get(url: string, params?: { SESSION_TOKEN?: string }) { const status = await this.auth() if (!status || !this.token) { return null } try { const response = await axiosInstance.get(url, { params: { ...params, SESSION_TOKEN: this.token }, headers: { 'Content-Type': 'application/json', }, }) return response.data } catch (err) { throw err } } })()
2. Promise+Axios方案优化(改用async/await)
原方案存在Promise嵌套过多的问题,用async/await可以大幅简化代码,提升可读性,优化后的完整代码如下:
import axiosInstance from './axiosInstance' export default new (class BmRequest { // 类名改为大驼峰,符合TS编码规范 private username = 'user' private password = '123456' private token: string | null = null private tokenInProcess: Promise<boolean> | boolean | undefined = false public async auth(): Promise<boolean> { // 避免重复发起认证请求 if (this.tokenInProcess instanceof Promise) { return this.tokenInProcess } // 已有有效token,直接返回成功 if (this.token) { return true } try { const response = await axiosInstance.post('/auth', { login: this.username, password: this.password, }) if (response.status === 200) { this.token = response.data.SESSION_TOKEN this.tokenInProcess = undefined return true } this.tokenInProcess = false return false } catch (err) { this.tokenInProcess = false console.error('认证失败:', err) return false } } public async get(url: string, params?: Record<string, unknown>) { const isAuthenticated = await this.auth() if (!isAuthenticated || !this.token) { return null } try { const response = await axiosInstance.get(url, { params: { ...params, SESSION_TOKEN: this.token, }, headers: { 'Content-Type': 'application/json', }, }) return response.data } catch (err) { throw err // 让调用方处理错误 } } })()
优化点说明
- 用
async/await替代Promise链式调用,消除回调嵌套,逻辑更线性清晰 - 给类内部成员加上
private修饰符,封装内部状态,符合TS封装原则 - 移除不必要的外层
Promise包装,减少冗余代码 - 错误处理更集中,认证失败时重置状态并打印错误信息
params参数改为通用的Record<string, unknown>,支持传入其他自定义参数
内容的提问来源于stack exchange,提问作者tesicg
相关产品推荐
相关产品推荐

