0

I have a component like this

type inputProps = {
  value: string | number | boolean
  onChange: (arg: string | number | boolean) => void
}

const Input = ({value, onChange}: inputProps) => {
  return <div />
}

const OtherComponent = () => {
  const [value, setValue] = React.useState(5)

  // onChange type not compatible
  return <Input  value={value} onChange={setValue} />
}

const AnotherComponent = () => {
  const [value, setValue] = React.useState('Hey')

  // onChange type not compatible
  return <Input  value={value} onChange={setValue} />
}

playground link

Is it possible to make the arg of the onChange function dependent on the value?

cubefox
  • 1,251
  • 14
  • 29

2 Answers2

2

Yes. It is possible using Generic Component

type InputProps<T> = {
  value: T;
  onChange: (arg: T) => void;
};

type AllowedTypes = string | boolean | number>;
    
const Input = <T extends AllowedTypes>({ value, onChange }: InputProps<T>) => {
  return <div />;
};
vighnesh153
  • 4,354
  • 2
  • 13
  • 27
  • thanks! the `` looks a bit like magic rn, do we have any docs on what it does? – cubefox Oct 17 '22 at 15:27
  • You can check this out for that syntax: https://stackoverflow.com/questions/32308370/what-is-the-syntax-for-typescript-arrow-functions-with-generics – vighnesh153 Oct 19 '22 at 07:42
0

You can first define the InputProps as generic.

type InputProps<T extends string | number | boolean> = {
  value: T;
  onChange: (arg: T) => void;
};

Then you can use type union for different types.

const Input = ({
  value,
  onChange,
}: InputProps<string> | InputProps<number> | InputProps<boolean>) => {
  return <div />;
};

const OtherComponent = () => {
  const [value, setValue] = React.useState(5);

  return <Input value={value} onChange={setValue} />;
};

const AnotherComponent = () => {
  const [value, setValue] = React.useState('Hey');

  return <Input value={value} onChange={setValue} />;
};
vighnesh153
  • 4,354
  • 2
  • 13
  • 27