TypeScript构造函数内调用异步函数为何返回类实例而非预期字符串?
问题分析与解决
问题场景
我编写了如下类:
export class getPlatformShopIdByCode { private shopCode:string; constructor(shopCode:string){ this.shopCode = shopCode; this.getPlatformShopIdByCode() } public getPlatformShopIdByCode = async ():Promise<string |null> => { const queryResult = await getRepository(Shop) .createQueryBuilder() .select("shop") .from(Shop,"shop") .where({shopCode:this.shopCode}) .getOne() if(Boolean(queryResult!.platformFlag) !== true){ return null; } return queryResult!.shopId; } }
调用代码如下:
const shopId = await new getPlatformShopIdByCode(this.Dto.getEvent().body.shopCode) await new FetchPricingPatternQuery() .fetch( shopId, true, this.Dto.getEvent().body.goodsCode, this.Dto.getEvent().body.tenantCode, this.Dto.getEvent().body.genreCode)
调用.fetch()时出现错误:
Argument of type 'getPlatformShopIdByCode' is not assignable to parameter of type 'string'
我本意是在new实例化时执行getPlatformShopIdByCode()方法,期望得到该方法返回的string类型值,但实际返回的是getPlatformShopIdByCode类实例,请问问题出在哪里?
问题原因
new操作符的本质:new关键字的作用就是创建并返回类的实例对象,无论你在构造函数里执行了什么逻辑,它的返回值永远是类的实例,不可能是类中方法的返回值。- 构造函数调用异步方法的问题:构造函数里调用的
this.getPlatformShopIdByCode()是异步方法,但构造函数本身不能标记为async,这里调用后不仅无法获取返回值,还会导致未捕获的Promise异常(因为没有处理这个异步方法的结果)。
解决方法
方案1:改成工具函数(推荐,更简洁)
直接把类改成独立的异步函数,调用时直接await就能拿到需要的结果:
export async function getPlatformShopIdByCode(shopCode: string): Promise<string | null> { const queryResult = await getRepository(Shop) .createQueryBuilder() .select("shop") .from(Shop, "shop") .where({ shopCode }) .getOne(); // 用可选链避免空值报错,逻辑更严谨 if (!queryResult?.platformFlag) { return null; } return queryResult.shopId; }
调用代码修改为:
const shopId = await getPlatformShopIdByCode(this.Dto.getEvent().body.shopCode); await new FetchPricingPatternQuery() .fetch( shopId, true, this.Dto.getEvent().body.goodsCode, this.Dto.getEvent().body.tenantCode, this.Dto.getEvent().body.genreCode );
方案2:保留类并修正逻辑
如果一定要用类,需要实例化后主动调用异步方法获取结果,同时移除构造函数里的异步方法调用:
// 类名遵循TS规范改为大驼峰 export class GetPlatformShopIdByCode { private shopCode: string; constructor(shopCode: string) { this.shopCode = shopCode; // 移除构造函数里的异步方法调用 } // 方法名修改,避免和类名重复 public async getPlatformShopId(): Promise<string | null> { const queryResult = await getRepository(Shop) .createQueryBuilder() .select("shop") .from(Shop, "shop") .where({ shopCode: this.shopCode }) .getOne(); if (!queryResult?.platformFlag) { return null; } return queryResult.shopId; } }
调用代码修改为:
const shopService = new GetPlatformShopIdByCode(this.Dto.getEvent().body.shopCode); const shopId = await shopService.getPlatformShopId(); await new FetchPricingPatternQuery() .fetch( shopId, true, this.Dto.getEvent().body.goodsCode, this.Dto.getEvent().body.tenantCode, this.Dto.getEvent().body.genreCode );
内容的提问来源于stack exchange,提问作者Heisenberg
相关产品推荐
相关产品推荐

