1

This might be very specific and tricky but struggling to find a solution here.

Essentially we (the project I'm on) have wrappers around some of our Form controls to keep all the handler/setup boilerplate and I'm having trouble with the Select component that wraps the Select from the react-select library.

react-use-form-state exposes the 'raw' type to work with custom controls where you update the value yourself with the exposed setField method. This library also allows a custom type declaration to define your forms state:

const [ formState, { raw } ] = useFormState<FormSchema>()

To use this raw type in the custom component, the Input type behind this is generic where the type is the of your form state.

However, if I remove this extra level of abstraction and use it directly in the same function that instantiates the state with the type it works fine:

What I'm asking I guess is how would I type this correctly in the CustomSelect component to satisfy typescript correctly.

Codesandbox of minimum code here

2 Answers 2

2

Hey I think I managed to get your type defs working by extending the use of ValueType in your select component definition.

Here's the working fork of your codesandbox

import * as React from "react";
import Select, { ValueType } from "react-select";

interface Props<ValueType> {
  controls: Inputs<ValueType>;
  name: keyof ValueType;
  options: SelectOption[];
  label?: string;
  formState: FormState<ValueType, StateErrors<ValueType, string>>;
};

export function CustomSelect<ValueType extends {} = string>(
  props: Props<ValueType>
) {
  const { controls, options, formState, name } = props;

  const handleChange = (option: any) => {
    formState.setField(name, option);
  };

  return (
    <Select
      {...controls.raw({ name })}
      options={options}
      onChange={handleChange}
      value={formState.values[name]}
    />
  );
}

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

1 Comment

thanks for the suggestion, oddly, this works fine in Codesandbox, but in my actual project (running TS 3.7.2) this still fails, not sure if this is affecting it, thanks for the help though!
0

Ended up fixing this by simply passing in the values that were required, rather than trying to pull them off the parent object that relied on the types.

I still would like to know if there was a way to infer the type correctly when passed from a parent but can't think of a way/if it's even possible.

// Custom Select:
type Props<T> = {
  controls: Inputs<T>;
  name: keyof T;
  options: SelectOption[];
  value: ValueType<SelectOption>; ***
  setField: (name: keyof T, value: ValueType<SelectOption>) => void; ***
};

const handleChange = (option: ValueType<SelectOption>) => {
  setField(name, option);
};

return (
  <Select
    {...controls.raw({ name })}
    options={options}
    onChange={handleChange}
    value={value}
  />
);

// Usage:
<CustomSelect
  controls={inputs}
  name="dropdown"
  options={options}
  value={formState.values.dropdown}
  setField={formState.setField}
/>

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.