You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript异步函数返回类型问题:void与IVerifiedCity冲突

解决TypeScript辅助函数返回类型冲突问题

核心问题分析

你遇到的错误源于TypeScript的类型规则:void仅能作为函数的直接返回类型或特定泛型变量使用,不能放在Promise的泛型联合类型中。而你的函数逻辑试图同时返回业务数据(IVerifiedCity)和触发Express错误流转(调用next(new AppError())),这直接导致了类型声明的冲突。

两种可行解决方案

方案1:分离辅助函数与错误处理(推荐,符合MVC职责分离)

让辅助函数仅负责数据验证并返回结果/空值,将错误处理(调用next)交给上层中间件,既清晰又符合分层架构:

// 辅助函数:专注验证逻辑,返回数据或null
async function verifyCityInDb(cityId: string): Promise<IVerifiedCity | null> {
  const city = await CityModel.findById(cityId);
  if (!city) {
    return null;
  }
  return { id: city._id, name: city.name } as IVerifiedCity;
}

// 中间件:处理错误流转和请求上下文挂载
async function cityMiddleware(req: Request, res: Response, next: NextFunction) {
  const city = await verifyCityInDb(req.params.cityId);
  if (!city) {
    return next(new AppError('City not found', 404));
  }
  req.city = city; // 将验证后的数据挂载到请求对象
  next();
}

方案2:在错误路径终止函数执行

如果坚持在辅助函数中调用next,可以在调用next后返回一个永远不会解析的Promise,让TypeScript认定函数始终返回IVerifiedCity类型:

async function verifyCityInDb(cityId: string, next: NextFunction): Promise<IVerifiedCity> {
  const city = await CityModel.findById(cityId);
  if (!city) {
    next(new AppError('City not found', 404));
    // 返回pending状态的Promise,终止函数执行流,满足TS类型要求
    return new Promise(() => {});
  }
  return { id: city._id, name: city.name } as IVerifiedCity;
}

也可以用抛出异常的方式(该异常不会被Express处理,仅用于TypeScript类型推断):

async function verifyCityInDb(cityId: string, next: NextFunction): Promise<IVerifiedCity> {
  const city = await CityModel.findById(cityId);
  if (!city) {
    next(new AppError('City not found', 404));
    throw new Error('City verification failed');
  }
  return { id: city._id, name: city.name } as IVerifiedCity;
}

关键提醒

避免在函数中混合返回业务数据和触发错误流转,这不仅会导致类型混乱,也违背了单一职责原则。TypeScript对void的限制本质是为了明确函数语义:void代表无返回值,而Promise的泛型应该是函数成功时返回的具体值。

内容的提问来源于stack exchange,提问作者Kévin WITZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 15:01:02