如何为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
相关产品推荐
相关产品推荐

