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

无需重载,如何通过回调实现TypeScript类型收窄?

解决方案:泛型+映射类型替代函数重载

要实现根据传入的颜色筛选条件,让回调函数自动识别对应实体类型,不需要依赖函数重载,可以通过泛型约束+类型映射来实现,具体步骤如下:

1. 建立颜色与实体类型的映射

首先定义一个映射类型,把每个颜色和对应的具体实体类型绑定:

type ColorEntityMap = {
  red: RedEntity;
  blue: BlueEntity;
  green: GreenEntity;
};

2. 将onMessage改为泛型函数

通过泛型参数关联颜色参数和回调函数的参数类型,让TypeScript能根据传入的颜色自动推导回调参数的具体类型:

function onMessage<TColor extends Color>(
  color: TColor,
  callback: (entity: ColorEntityMap[TColor]) => void
) {
  const lastEntity = getLastEntity();
  if (lastEntity.color !== color) {
    return;
  }
  // 运行时已验证颜色匹配,可安全断言类型
  callback(lastEntity as ColorEntityMap[TColor]);
}

3. 可选:用类型守卫替代断言(更安全)

如果不想用类型断言,可以写一个自定义类型守卫,让TypeScript在编译期确认实体类型:

function isEntityOfColor<TColor extends Color>(
  entity: Entity<Color>,
  color: TColor
): entity is ColorEntityMap[TColor] {
  return entity.color === color;
}

// 修改onMessage中的判断逻辑
function onMessage<TColor extends Color>(
  color: TColor,
  callback: (entity: ColorEntityMap[TColor]) => void
) {
  const lastEntity = getLastEntity();
  if (isEntityOfColor(lastEntity, color)) {
    callback(lastEntity); // 无需断言,TS自动识别类型
  }
}

效果验证

调用onMessage时,TypeScript会根据第一个参数的颜色,自动推导回调参数的具体类型:

onMessage("red", (entity) => {
  // 报错:类型"blue"不能赋值给类型"red"
  // entity.color === "blue";
  // 正常识别:entity是RedEntity,可访问isRed属性
  console.log(entity.isRed);
});

onMessage("blue", (entity) => {
  console.log(entity.isBlue); // 正确识别为BlueEntity
});

方案优势

相比函数重载,这种方式的扩展性更强:如果新增颜色和对应的实体类型,只需要更新ColorEntityMap即可,无需修改函数的重载定义,代码更简洁易维护。

内容的提问来源于stack exchange,提问作者nehalist

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 20:40:49