React & TypeScript:根据传入Props实现参数类型条件判断
React组件根据Props存在性设置函数参数的条件类型
要实现当传入objectKey时handleDateChange参数为对象类型,未传入时为Dayjs类型,核心是利用TypeScript的可辨识联合类型或泛型条件类型让TypeScript自动推导参数类型,以下是两种可行方案:
方案一:可辨识联合类型(推荐,无需显式泛型)
定义两种互斥的Props类型,通过objectKey的存在性作为辨识符,TypeScript会自动根据传入的Props推断函数参数类型:
import { Dayjs } from 'dayjs'; import React from 'react'; // 无objectKey时的Props类型 type DatePickerBaseProps = { handleDateChange: (value: Dayjs) => void; value: Dayjs; objectKey?: never; // 明确禁止传入该属性,或设为undefined }; // 有objectKey时的Props类型 type DatePickerWithObjectKeyProps = { handleDateChange: (value: { [x: string]: Dayjs }) => void; value: Dayjs; objectKey: string; // 强制要求传入字符串类型 }; // 合并为联合类型 type DatePickerProps = DatePickerBaseProps | DatePickerWithObjectKeyProps; const DatePicker = ({ handleDateChange, value, objectKey }: DatePickerProps) => { // 组件内部逻辑:根据objectKey决定传递的参数格式 const handleDateSelect = (selected: Dayjs) => { if (objectKey) { // TypeScript会自动识别此处handleDateChange接受对象参数 handleDateChange({ [objectKey]: selected }); } else { // 此处自动识别接受Dayjs参数 handleDateChange(selected); } }; // 示例渲染逻辑(需根据实际UI库调整) return ( <div> <input type="date" onChange={(e) => { const date = Dayjs(e.target.value); handleDateSelect(date); }} defaultValue={value.format('YYYY-MM-DD')} /> </div> ); };
为什么有效?
TypeScript会对联合类型做类型收窄:当检测到objectKey是字符串类型时,会自动将Props类型收窄为DatePickerWithObjectKeyProps,此时handleDateChange的参数类型就被锁定为对象;反之则收窄为DatePickerBaseProps,参数为Dayjs。
方案二:泛型条件类型
通过泛型参数控制objectKey的类型,结合条件类型动态生成handleDateChange的参数类型:
import { Dayjs } from 'dayjs'; import React from 'react'; type DatePickerProps<T extends string | undefined = undefined> = { handleDateChange: T extends string ? (value: { [x: string]: Dayjs }) => void : (value: Dayjs) => void; value: Dayjs; objectKey: T; }; const DatePicker = <T extends string | undefined = undefined>({ handleDateChange, value, objectKey }: DatePickerProps<T>) => { const handleDateSelect = (selected: Dayjs) => { if (objectKey) { handleDateChange({ [objectKey]: selected }); } else { handleDateChange(selected); } }; // 渲染逻辑同方案一 return <div>{/* 日期选择UI */}</div>; };
使用方式
- 未传
objectKey:DatePicker({ handleDateChange: (d) => {}, value: Dayjs() })(可省略泛型参数,TypeScript自动推导) - 传入
objectKey:DatePicker({ handleDateChange: (obj) => {}, value: Dayjs(), objectKey: 'startDate' })
注意事项
- 如果需要在有
objectKey时同步修改value的类型(比如从Dayjs改为对象),只需修改对应Props类型中的value字段即可 - 组件内部逻辑中,TypeScript会自动根据
objectKey的存在性做类型检查,无需额外类型断言
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

