You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 02:52:44