TypeScript如何动态传递类型给函数,避免手动维护联合类型?
解决方案
可以通过类型推断与提取实现动态关联AnimlState的data类型,无需手动维护foo的参数类型:
步骤1:提取AnimlState中所有属性的data类型联合
定义一个工具类型,自动从AnimlState中提取所有可选属性的data字段类型:
type AnimalData = AnimlState[keyof AnimlState] extends { data: infer T } ? T : never;
这个类型会自动遍历AnimlState的所有键,提取对应属性里data的类型,最终生成CatState[] | DogState[]的联合类型(后续AnimlState新增/修改属性时,该类型会自动更新)。
步骤2:使用动态类型定义foo函数
用上面的AnimalData作为foo的参数类型:
const foo = (data: AnimalData) => { // 函数逻辑 };
完整示例代码
修正原代码中的语法错误后,完整实现如下:
// 假设已定义基础类型 interface CatState {} interface DogState {} interface CatStateProps { data: CatState[], food: number[] } interface DogStateProps { data: DogState[], food: string[] } type AnimlState= { cat?: CatStateProps , dog?: DogStateProps, }; // 提取动态data类型 type AnimalData = AnimlState[keyof AnimlState] extends { data: infer T } ? T : never; const foo = (data: AnimalData) => { // 编写你的业务逻辑 }; const catsAndDogs: AnimlState = { cat: {data: [], food: []}, dog: {data: [], food: []}, }; let {dog} = catsAndDogs; if(dog) { let {data} = dog; foo(data); // 此时data类型自动匹配AnimalData,不会变为any }
原理说明
AnimlState[keyof AnimlState]会获取AnimlState所有属性的类型联合(即CatStateProps | DogStateProps | undefined)- 通过条件类型
extends { data: infer T },从每个属性类型中提取data的类型T,最终合并为联合类型 - 后续如果
AnimlState新增其他动物属性(比如rabbit?: RabbitStateProps),AnimalData会自动包含RabbitState[],无需修改foo函数
内容的提问来源于stack exchange,提问作者four-eyes
相关产品推荐
相关产品推荐

