Home  >  Q&A  >  body text

React and TypeScript - Use conditional parameter types if props exist

In React, I'm trying to set a conditional type in a function parameter based on whether a prop is passed in the component.

Here is an example, I have this component:

const DatePicker = ({
  handleDateChange,
  value,
  objectKey,
}: {
  handleDateChange: (value: Dayjs | { [x: string]: Dayjs }) => void;
  value: Dayjs;
  objectKey?: string;
}) => JSX

What I want to do is, if "objectKey" is passed as props, then the type of "value" parameter in handleDateChange function will be { [x: string]: Dayjs }, otherwise it will be value: Dayjs.

Does anyone know how to implement this?

P粉148434742P粉148434742481 days ago701

reply all(1)I'll reply

  • P粉852578075

    P粉8525780752023-07-19 00:24:54

    You can achieve similar effects through function overloading.

    // first overload signature
    function DatePicker({
      handleDateChange,
      value,
    }: {
      handleDateChange: (value: Dayjs) => void;
      value: Dayjs;
    }): JSX;
    // second overload signature
    function DatePicker({
      handleDateChange,
      value,
      objectKey,
    }: {
      handleDateChange: (value: { [x: string]: Dayjs }) => void;
      value: Dayjs;
      objectKey?: string;
    }): JSX;
    // implementation
    function DatePicker({
      handleDateChange,
      value,
      objectKey,
    }: {
      handleDateChange: ((value: Dayjs) => void) | ((value: { [x: string]: Dayjs }) => void);
      value: Dayjs;
      objectKey?: string;
    }) {
      // ...
    }
    

    Using this method, DatePicker can only be called according to your definition, but the implementation part does not know the association between handleDateChange and objectKey, so it still needs to be handled explicitly.

    Without knowing any details about DatePicker, I think it's better to just use a signature and let the parent component make adjustments to the DatePicker, rather than having the DatePicker handle special cases from the parent component.

    reply
    0
  • Cancelreply