1

New to Typescript here. I have a Material UI Slider that I'd like to set my age state variable with, but I'm getting a Typescript error due to the typing of age being number and onChange value being number | number[]. How can I tell onChange to always expect a number?

code:

      <Slider
        defaultValue={25}
        step={1}
        min={0}
        max={100}
        valueLabelDisplay="auto"
        onChange={handleAgeSliderChange}
      />

onChange: (use Redux store)

    const handleAgeSliderChange = (event:any, newValue: number | number[]) =>{
        const new_inputs = { ...props.userInput, age: newValue}
        props.updateUserInputs(new_inputs)
    }

and the error:

  Types of property 'age' are incompatible.
    Type 'number | number[]' is not assignable to type 'number'.
      Type 'number[]' is not assignable to type 'number'.

EDIT: Some more details:

in ActionCreators.tsx

export const updateUserInputs = (input: UserInputs) : ActionTypes.UserInputActions => ({
    type: ActionTypes.UPDATE_USER_INPUTS,
    payload: input
})

in userinputs.tsx

const initialState: UserInputs = {
    age: 25, 
    ethnicity: "white",
    country: "US",
    smoking: false
}

export const userInputReducer = (
    state = initialState,
    action: ActionTypes.UserInputActions
  ) => {
    switch (action.type) {
      case ActionTypes.UPDATE_USER_INPUTS:
          const new_input = action.payload
          return {...state, userInput: new_input}
    default:
        return {...state}    
      }
  };

in types.tsx

export interface UserInputs {
  age: number;
  ethnicity: string;
  country: string;
  smoking: boolean;
}
Ryan Wilkins
  • 127
  • 3
  • 6
  • Can you show us what the `updateUserInputs` function looks like? I assume the error comes from there. – Dean James Dec 16 '20 at 20:03
  • I added some more details. I'm new to Redux & React in general, but everything seems to be hooked up correctly, it's just complaining that `number` doesn't map to `number[]` – Ryan Wilkins Dec 16 '20 at 20:12
  • I found this: https://stackoverflow.com/questions/33256274/typesafe-select-onchange-event-using-reactjs-and-typescript Tried `var value: number = newValue as any` and it seems to work. Is this best practices? – Ryan Wilkins Dec 16 '20 at 20:19
  • No, `any` is the loosest type which kinda makes it pointless to use TypeScript. Instead of `any` you can cast it to a `number`, but this still ignores the scenario of when it potentially is an array of numbers. – Dean James Dec 16 '20 at 23:19
  • Any idea if there is a better solution that doesn't involve somehow rewriting onChange? – Ryan Wilkins Dec 17 '20 at 01:02
  • In case others end up here from searching on a similar error with the `event` typing from this Slider component, I was able to get it to work with `changeHandler = (event: React.SyntheticEvent | Event, newThresholdValue: number[]) => { ... }` – Benvoluto Jan 15 '23 at 01:00

1 Answers1

0

You can handle it in a change handler like the one below.

const handleAgeSliderChange = (_ : Event, value: number | number[]) => {
       const age = Array.isArray(value) ? value[0] : value;
       props.updateUserInputs(age);
}
chety
  • 136
  • 4