1

I am trying to use react-dates with Typescript, but cannot figure out how to define the types.

The following TS/React code is giving the error

Argument of type '"startDate" | "endDate" | null' is not assignable to parameter of type 'SetStateAction'. Type '"startDate"' is not assignable to type 'SetStateAction'.

My code is based on this, is there a simplier way to write this code? Thank you!

import React, { useState } from 'react';

import moment from 'moment';
import "react-dates/initialize";
import "react-dates/lib/css/_datepicker.css";
import { DateRangePicker } from 'react-dates';

interface IHandleDatesChange {
    startDate: moment.Moment | null,
    endDate: moment.Moment | null,
}

export function Foo(): JSX.Element {
    const [ startDate, setStartDate ] = useState<moment.Moment | null>(moment('1990-01-01'));
    const [ endDate, setEndDate ] = useState<moment.Moment | null>(moment(moment().endOf('year')));
    const [ focusedInput, setFocusedInput ] = useState(null);

    const handleDatesChange = ({ startDate, endDate}: IHandleDatesChange) => {
        setStartDate(startDate);
        setEndDate(endDate);
    }

    return (
        <DateRangePicker
            startDate={startDate}
            startDateId='daterangepicker_start_date'
            endDate={endDate}
            endDateId='daterangepicker_end_date'
            onDatesChange={handleDatesChange}
            focusedInput={focusedInput}
            onFocusChange={(focusedInput) => setFocusedInput(focusedInput)}   // <== ERROR OCCURS
        />
    )
}

yarn.lock

react-dates@^21.8.0:
  version "21.8.0"
  resolved "https://registry.yarnpkg.com/react-dates/-/react-dates-21.8.0.tgz#355c3c7a243a7c29568fe00aca96231e171a5e94"
  integrity sha512-PPriGqi30CtzZmoHiGdhlA++YPYPYGCZrhydYmXXQ6RAvAsaONcPtYgXRTLozIOrsQ5mSo40+DiA5eOFHnZ6xw==
  dependencies:
    airbnb-prop-types "^2.15.0"
    consolidated-events "^1.1.1 || ^2.0.0"
    enzyme-shallow-equal "^1.0.0"
    is-touch-device "^1.0.1"
    lodash "^4.1.1"
    object.assign "^4.1.0"
    object.values "^1.1.0"
    prop-types "^15.7.2"
    raf "^3.4.1"
    react-moment-proptypes "^1.6.0"
    react-outside-click-handler "^1.2.4"
    react-portal "^4.2.0"
    react-with-direction "^1.3.1"
    react-with-styles "^4.1.0"
    react-with-styles-interface-css "^6.0.0"

...

"@types/react-dates@^21.8.1":
  version "21.8.1"
  resolved "https://registry.yarnpkg.com/@types/react-dates/-/react-dates-21.8.1.tgz#f90b30895e22d15f42c64be6bbafb1796b5f05f8"
  integrity sha512-zgBf0SM6dcDPR29x3bCzSypK0c2+EKDkR4NNyBCwH2GyL/AgIvJ0bQ6n2z1s468SXS2QbzCMJtF831vG7iGkjg==
  dependencies:
    "@types/react" "*"
    "@types/react-outside-click-handler" "*"
    moment "^2.26.0"

...

moment@>=1.6.0, moment@^2.26.0, moment@^2.29.1:
  version "2.29.1"
  resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
  integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==

2 Answers 2

3

Edit:

You haven't passed a type to your focusedInput state. If you check the @types/react-dates definitions, the onFocusChange prop expects the callback argument to be a specific type: FocusedInputShape which is a string union 'startDate' | 'endDate'.

To fix, update your state init:

const [ focusedInput, setFocusedInput ] = useState<FocusedInputShape | null>(null);

Original answer:

I seem to recall hitting this issue (or very similar) before and it turned out to be a moment version mismatch between the dependency installed in my project and the dependency installed by react-dates.

Check which versions are installed and if they do not match, up-/down-grade your project version if you can to see if it makes a difference.

Sign up to request clarification or add additional context in comments.

4 Comments

I've updated the question with the versions of moment and react-dates. Do you happen to recall the versions that you used when it worked for you?
I don't remember off the top of my head but will check if I can find the old project. Is moment a dependency on your project? I would suggest ensuring you use the exact version listed in the react-dates deps (2.29.1) and see if it helps at all. The community typings @types/react-dates also use a different version 2.26.0 which isn't ideal.
Thanks! Yes [email protected] is a dependency of my project. I have tried downgrading to @types/[email protected] while maintaining [email protected], still getting the same error. Wonder if there's something wrong with my Typescript code...
Did you solve this in the end? I think I've spotted the actual issue and it's not conflicting versions of moment - you need to pass a type to your focusedInput state. I'll update my answer with a suggested fix.
1

Here is how I got the basic example to work with TS.

import React, { ReactNode, useState } from 'react'
import moment, { Moment } from 'moment'
import 'react-dates/initialize'
import 'react-dates/lib/css/_datepicker.css'
import { DateRangePicker, FocusedInputShape } from 'react-dates'

const Calendar = () => {
  const [startDate, setStartDate] = useState<Moment | null>(moment())
  const [endDate, setEndDate] = useState<Moment | null>(null)
  const [focusedInput, setFocusedInput] = useState<FocusedInputShape | null>(
    null
  )

  const handlendDatesChange = (arg: {
    startDate: Moment | null
    endDate: Moment | null
  }) => {
    setStartDate(arg.startDate)
    setEndDate(arg.endDate)
  }

  const handleFocusChange = (arg: FocusedInputShape | null) => {
    setFocusedInput(arg)
  }

  return (
    <DateRangePicker
      /**
       * Tip for who is new to TS: You can view the type definition on hover in VSCode.
       * You can use these types on their respective useState and function.
       */
      startDate={startDate} // moment.Moment | null;
      startDateId="your_unique_start_date_id" // moment.Moment | null;
      endDate={endDate} // momentPropTypes.momentObj or null,
      endDateId="your_unique_end_date_id" // string;
      onDatesChange={handlendDatesChange} // (arg: { startDate: moment.Moment | null; endDate: moment.Moment | null }) => void;
      focusedInput={focusedInput} // FocusedInputShape | null;
      onFocusChange={handleFocusChange} // (arg: FocusedInputShape | null) => void;
    />
  )
}

export default Calendar

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.