React+TypeScript实现TimePicker组件的类型错误问题求助
修复React TimePicker组件中的TypeScript类型不匹配问题
问题原因
出现类型错误是因为当你从联合类型中解构出range和onChange后,TypeScript无法推断这两个属性之间的关联关系。此时onChange会被识别为两个函数签名的联合类型,TypeScript要求传入的参数必须同时兼容这两个类型(也就是错误提示中的string & string[],这是一个不可能存在的类型)。
解决方案1:保留完整Props对象实现类型收窄
不要提前解构所有props,保留完整的props对象。直接在props对象上检查range这个判别式属性,TypeScript会自动收窄整个props的类型,从而正确推断onChange的函数签名:
import { useEffect } from 'react'; type SingleTime = { value: string; onChange: (val: string) => void; range: false; }; type RangeTime = { value: string[]; onChange: (val: string[]) => void; range: true; }; type TimePickerProps = { min?: null | string; max?: null | string; }; type FinalProps = (TimePickerProps & SingleTime) | (TimePickerProps & RangeTime); export default function TimePicker(props: FinalProps) { const { min = null, max = null } = props; useEffect(() => { if (!props.range) { props.onChange('10:30'); // TypeScript此时能识别这是单时间选择的onChange } else { props.onChange(['10:30', '11:30']); // TypeScript此时能识别这是时间范围选择的onChange } }, [props.range, props.onChange]); return <div></div>; }
解决方案2:使用类型守卫配合解构后的Props
如果你更倾向于解构props,可以创建一个类型守卫函数,根据range的值明确收窄onChange的类型:
import { useEffect } from 'react'; type SingleTime = { value: string; onChange: (val: string) => void; range: false; }; type RangeTime = { value: string[]; onChange: (val: string[]) => void; range: true; }; type TimePickerProps = { min?: null | string; max?: null | string; }; type FinalProps = (TimePickerProps & SingleTime) | (TimePickerProps & RangeTime); // 类型守卫:根据range值判断onChange的类型 function isSingleOnChange( range: boolean, onChange: FinalProps['onChange'] ): onChange is (val: string) => void { return !range; } export default function TimePicker({ value, onChange, range = false, min = null, max = null, }: FinalProps) { useEffect(() => { if (isSingleOnChange(range, onChange)) { onChange('10:30'); } else { onChange(['10:30', '11:30']); } }, [range, onChange]); return <div></div>; }
内容的提问来源于stack exchange,提问作者Ahmad Reza
相关产品推荐
相关产品推荐

