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

如何标记辅助函数已校验event.body非空以消除TS(18047)错误?

让TypeScript识别辅助函数已完成非空校验的解决方案

我有一个可复用的辅助函数:

const eventCommonChecks = (event: APIGatewayEvent): any => {
  if(!event.body) {
    return {
      "status": 400,
      "body": "Missing body"
    }
  }

  // 其他若干校验逻辑
}

调用这个辅助函数时,如果event.body为空,调用方会直接返回错误响应,此时event.body必然非空,但TypeScript编译器仍报错:'event.body' is possibly 'null'.ts(18047),必须用可选链调用才能通过检查。想知道怎么修饰这个辅助函数,让TypeScript识别它已经完成了event.body的非空校验。

调用方函数示例:

const someLambda = (event: APIGatewayEvent): any => {
  const commonEventCheckResponse = eventCommonChecks(event);
  if (commonEventCheckResponse) {
    return commonEventCheckResponse;
  }

  // 报错:'event.body' is possibly 'null'.ts(18047)
  if (!event.body.someFieldInBody) {
    return {
      "status": 400,
      "body": "Missing someFieldInBody"
    }
  }
}

要解决这个问题,核心是让TypeScript编译器理解:经过eventCommonChecks校验后,event.body不再是null或undefined。可以用类型谓词或断言函数两种方式实现,具体方案如下:

方法一:使用类型谓词(推荐)

修改辅助函数的返回类型,通过类型谓词标记校验通过后event的类型,让TypeScript自动推断event.body非空:

// 定义校验后的类型,确保body非空
type ValidatedAPIGatewayEvent = APIGatewayEvent & { body: NonNullable<APIGatewayEvent['body']> };

function eventCommonChecks(event: APIGatewayEvent): event is ValidatedAPIGatewayEvent | { status: number; body: string } {
  if (!event.body) {
    return {
      "status": 400,
      "body": "Missing body"
    } as const;
  }

  // 其他校验逻辑,不通过时返回错误对象
  // ...

  // 所有校验通过,返回true,此时TypeScript会认定event是ValidatedAPIGatewayEvent类型
  return true;
}

调用方只需调整判断逻辑,区分返回值是布尔值(校验通过)还是错误对象:

const someLambda = (event: APIGatewayEvent): any => {
  const checkResult = eventCommonChecks(event);
  if (typeof checkResult !== 'boolean') {
    return checkResult;
  }

  // 这里TypeScript自动识别event.body非空,不会再报错
  if (!event.body.someFieldInBody) {
    return {
      "status": 400,
      "body": "Missing someFieldInBody"
    };
  }

  // 后续业务逻辑...
};

方法二:使用断言函数

如果希望辅助函数在校验失败时直接抛出错误(而非返回错误对象),可以用断言函数强制TypeScript认定校验通过后event.body非空:

function eventCommonChecks(event: APIGatewayEvent): asserts event is APIGatewayEvent & { body: NonNullable<APIGatewayEvent['body']> } {
  if (!event.body) {
    throw new Error(JSON.stringify({ status: 400, body: "Missing body" }));
  }

  // 其他校验逻辑,失败时抛出错误
  // ...
}

调用方需要捕获错误并返回响应:

const someLambda = (event: APIGatewayEvent): any => {
  try {
    eventCommonChecks(event);
  } catch (err) {
    return JSON.parse((err as Error).message);
  }

  // 此处event.body已被断言为非空,编译器不再报错
  if (!event.body.someFieldInBody) {
    return {
      "status": 400,
      "body": "Missing someFieldInBody"
    };
  }

  // 后续业务逻辑...
};

核心原理说明

  • 类型谓词:通过event is ValidatedAPIGatewayEvent告诉编译器,当函数返回true时,传入的event参数符合指定的校验后类型;返回错误对象则表示校验失败。
  • 断言函数:通过asserts event is ...声明,只有当函数正常执行完毕(未抛出错误)时,event才符合断言的类型,强制编译器认可后续代码中event.body非空。

内容的提问来源于stack exchange,提问作者scott.korin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 13:33:18