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

TypeScript泛型解析为交叉类型问题及body.name访问方案咨询

TypeScript交叉类型SignRequest & {}成因与 idiomatic 访问方案

一、为什么body的类型是SignRequest & {}?

你在SignUpController的handle方法里,把SignRequest声明成了泛型参数,这会遮蔽外部定义的同名SignRequest接口。TypeScript会将这个泛型参数视为一个无任何约束的未知类型,结合HttpRequest<T>中body?: T的定义:

  • 初始时httpRequest.body的类型是T | undefined | null
  • 当你通过if判断排除null和undefined后,TypeScript会做类型收窄,将其变为T & {}(因为{}类型可以排除null和undefined)

此时的SignRequest是无约束泛型,自然没有name属性,所以访问body.name会报错。

二、符合TypeScript风格的body.name访问方式

方案1:移除不必要的泛型(推荐)

SignUpController是专门处理注册请求的控制器,不需要泛型,直接指定请求和响应的类型为外部的SignRequest接口即可:

export class SignUpController implements Controller {
  handle(httpRequest: HttpRequest<SignRequest>): HttpResponse<SignRequest> {

    if (httpRequest.body === null || httpRequest.body === undefined) {
      throw new Error("Bad Request")
    }

    const body = httpRequest.body; // 类型为SignRequest
    console.log(body.name); // 正常访问,无类型错误

    throw new Error("Not implemented exception");
  }
}

方案2:给泛型添加约束(适用于通用控制器场景)

如果需要控制器支持多种请求类型,给泛型参数添加继承约束,确保它包含SignRequest的属性:

export class SignUpController implements Controller {
  handle<T extends SignRequest>(httpRequest: HttpRequest<T>): HttpResponse<T> {

    if (httpRequest.body === null || httpRequest.body === undefined) {
      throw new Error("Bad Request")
    }

    const body = httpRequest.body; // 类型为T,继承自SignRequest
    console.log(body.name); // 类型检查通过

    throw new Error("Not implemented exception");
  }
}

内容的提问来源于stack exchange,提问作者Cássio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 02:50:40