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

如何为TypeScript泛型函数getAllBlueCars添加正确的类型标注

如何为TypeScript泛型函数getAllBlueCars添加正确的类型标注

我明白你现在的苦恼:写getAllBlueCars这个函数时,明明想根据传入的品牌返回对应类型的工厂数组,结果不仅遍历的car被识别成any,连返回值也变成了any[],虽然之前的方案能修正返回值类型,但car的类型问题还是没解决。

先看看你最初的代码问题出在哪:

const getAllBlueCars = (brand: Brands) => {
  const carBrand = allCars[brand]; // 类型是Mercedes | Audi
  // 这里car被推断为any,函数返回any[]
  return Object.values(carBrand).reduce((acc, car) => {
    if (car.color === "blue") {
      return [...acc, car.factory];
    }
    return acc;
  }, [])
}

因为carBrand是Mercedes | Audi的联合类型,TypeScript没办法自动把Object.values(carBrand)的元素类型收窄到具体的CarProps<MercedesFactory>或CarProps<AudiFactory>,所以只能把car标记为any,返回值自然也跟着变成any[]了。

接下来给你两个可行的解决方案,既能让car获得正确类型,又能让函数返回值根据传入品牌自动推断:

方案一:提前定义品牌-类型映射

先明确每个品牌对应的车型和工厂类型,让TypeScript有清晰的类型参照:

// 定义品牌到工厂类型的映射
type BrandToFactory = {
  mercedes: MercedesFactory;
  audi: AudiFactory;
};

// 定义品牌到车型集合的映射
type BrandToCars = {
  mercedes: Mercedes;
  audi: Audi;
};

// 改造泛型函数
const getAllBlueCars = <TBrand extends Brands>(brand: TBrand) => {
  const carBrand = allCars[brand] as BrandToCars[TBrand];
  // 现在car会被正确推断为CarProps<BrandToFactory[TBrand]>
  return Object.values(carBrand).reduce<BrandToFactory[TBrand][]>((acc, car) => {
    if (car.color === "blue") {
      return [...acc, car.factory];
    }
    return acc;
  }, []);
};

测试一下效果:

const allAudiBlueCarsFabric = getAllBlueCars("audi"); // 类型是AudiFactory[]
const allMercedesBlueCarsFabric = getAllBlueCars("mercedes"); // 类型是MercedesFactory[]

这里通过映射类型把泛型TBrand和具体的车型、工厂类型绑定,TypeScript能精准推断出carBrand的具体类型,car的类型自然就明确了,返回值也完全符合预期。

方案二:用条件类型自动推导(无需额外映射)

如果你不想额外定义映射类型,也可以直接通过条件类型从typeof allCars里推导所需类型:

const getAllBlueCars = <TBrand extends Brands>(brand: TBrand) => {
  const carBrand = allCars[brand];
  // 从车型集合里提取单个车型的类型
  type CarType = typeof carBrand extends Record<string, infer U> ? U : never;
  // 从车型类型里提取对应的工厂类型
  type FactoryType = CarType extends CarProps<infer F> ? F : never;
  
  return Object.values(carBrand).reduce<FactoryType[]>((acc, car) => {
    if (car.color === "blue") {
      return [...acc, car.factory];
    }
    return acc;
  }, []);
};

这个版本完全依赖TypeScript的类型推断能力,不需要额外定义映射类型,效果和方案一一致——car会被正确推断为对应品牌的CarProps类型,返回值也是精准的工厂类型数组。

备注:内容来源于stack exchange,提问作者Joel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 09:18:11