能否基于传入参数推断不同类型?TypeScript React组件实践
根据参数值推断不同类型的实现方案
你想要实现的是根据selectRange的布尔值,自动对应cb函数的参数类型,这个需求完全可以实现,问题出在React组件中解构参数时丢失了类型关联。
问题原因
你定义的FooProps是正确的联合类型,但当你解构{cb, selectRange}时,TypeScript会把这两个变量的类型拆解开:
cb被推断为((value: number) => void) | ((value: [number]) => void)selectRange被推断为boolean
此时两者的类型关联被切断,TypeScript无法判断selectRange为true时,cb对应的是哪个函数类型,导致直接调用报错。
解决方案
方案1:保留props对象,不直接解构
通过直接访问props对象的属性,TypeScript可以通过props.selectRange的取值自动窄化整个props的类型分支,从而正确识别cb的参数类型:
import React from 'react'; type FooProps = { baseProp: string } & ({ cb: (value: number) => void; selectRange: false } | { cb: (value: [number]) => void; selectRange: true }); const FooComp: React.FC<FooProps> = (props) => { if (props.selectRange) { props.cb([1, 2]); // 类型匹配,无报错 } else { props.cb(1); // 类型匹配,无报错 } return <div>{props.baseProp}</div>; };
方案2:解构后手动恢复类型关联(可选)
如果一定要解构参数,可以通过类型断言手动指定cb的类型,适合必须解构的场景:
const FooComp: React.FC<FooProps> = ({ cb, selectRange, baseProp }) => { if (selectRange) { (cb as (value: [number]) => void)([1, 2]); } else { (cb as (value: number) => void)(1); } return <div>{baseProp}</div>; };
类型定义优化(可选)
你可以把联合类型拆分为更清晰的子类型,可读性更好,功能完全等价:
type FooBaseProps = { baseProp: string }; type FooSingleSelectProps = FooBaseProps & { cb: (value: number) => void; selectRange: false; }; type FooRangeSelectProps = FooBaseProps & { cb: (value: [number]) => void; selectRange: true; }; type FooProps = FooSingleSelectProps | FooRangeSelectProps;
内容的提问来源于stack exchange,提问作者LoyalPotato
相关产品推荐
相关产品推荐

