Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass custom attributes and props #508

Closed
alvarotrigo opened this issue Mar 26, 2021 · 9 comments
Closed

Pass custom attributes and props #508

alvarotrigo opened this issue Mar 26, 2021 · 9 comments

Comments

@alvarotrigo
Copy link

I'm trying to add the ref attribute with the inputRef value:
I've read other issues such as #295 but I don't think any solves this problem so far?

import * as React from "react";
import { default as NumberFormat } from 'react-number-format';

export const InputCustom = ({
  inputRef,
  ...props
}: {
  inputRef?: React.Ref<HTMLInputElement>;
} & React.InputHTMLAttributes<HTMLInputElement>) => {
  return (
    <div className={"input-wrapper"}>
      <NumberFormat         
        thousandSeparator={true} 
        decimalScale={2}
        allowNegative={false}
        inputmode="numeric"
        
        ref={inputRef}

        {...props}
      />
     </div>
  );
};

I'm getting the following error:

17:05:13 webpack.1 | ERROR in app/InputCustom.tsx:33:9
17:05:13 webpack.1 | TS2769: No overload matches this call.
17:05:13 webpack.1 |   Overload 1 of 2, '(props: NumberFormatProps | Readonly<NumberFormatProps>): NumberFormat', gave the following error.
17:05:13 webpack.1 |     Type 'Ref<HTMLInputElement> | undefined' is not assignable to type 'LegacyRef<NumberFormat> | undefined'.
17:05:13 webpack.1 |       Type '(instance: HTMLInputElement | null) => void' is not assignable to type 'LegacyRef<NumberFormat> | undefined'.
17:05:13 webpack.1 |         Type '(instance: HTMLInputElement | null) => void' is not assignable to type '(instance: NumberFormat | null) => void'.
17:05:13 webpack.1 |           Types of parameters 'instance' and 'instance' are incompatible.
17:05:13 webpack.1 |             Type 'NumberFormat | null' is not assignable to type 'HTMLInputElement | null'.
17:05:13 webpack.1 |               Type 'NumberFormat' is missing the following properties from type 'HTMLInputElement': accept, align, alt, autocomplete, and 287 more.
17:05:13 webpack.1 |   Overload 2 of 2, '(props: NumberFormatProps, context: any): NumberFormat', gave the following error.
17:05:13 webpack.1 |     Type 'Ref<HTMLInputElement> | undefined' is not assignable to type 'LegacyRef<NumberFormat> | undefined'.
17:05:13 webpack.1 |     31 |         inputmode="numeric"
17:05:13 webpack.1 |     32 |         
17:05:13 webpack.1 |   > 33 |         ref={inputRef}

So far, and following this other issue #422 the only way to fix it seems to be by adding // @ts-ignore.

Any better workaround?

@s-yadav
Copy link
Owner

s-yadav commented Apr 7, 2021

The ref issue should be fixable, as we extend input the ref type is wrongly set. Will fix the ref issue.

For types of other custom props, need to explore a little.

@s-yadav s-yadav reopened this Apr 7, 2021
@s-yadav
Copy link
Owner

s-yadav commented Apr 9, 2021

Ohh, checked. Actually, this is not an issue. NumberFormat is a component, and inputRef is of type HTMLInputElement, which is why it throws an error.

Please refer. https://github.com/s-yadav/react-number-format/blob/master/README.md#getting-reference

Let if know if this doesn't fix the issue.

@s-yadav s-yadav closed this as completed Apr 9, 2021
@alvarotrigo
Copy link
Author

alvarotrigo commented Apr 15, 2021

@s-yadav is it possible to pass all props into NumberFormat component by using {...props}?
I seem to always get a typescript error preventing compilation when doing this:

<NumberFormat         
        thousandSeparator={true} 
        decimalScale={2}
        allowNegative={false}
        inputmode="numeric"
        
        // this generates the error:
        {...props}
      />
13:18:08 webpack.1 | ERROR in app/demo.js
13:18:08 webpack.1 | TS2769: No overload matches this call.
13:18:08 webpack.1 |   Overload 1 of 2, '(props: NumberFormatProps | Readonly<NumberFormatProps>): NumberFormat', gave the following error.
13:18:08 webpack.1 |     Type '{ accept?: string | undefined; alt?: string | undefined; autoComplete: string | undefined; autoFocus?: boolean | undefined; capture?: string | boolean | undefined; checked?: boolean | undefined; ... 286 more ...; value: (string & (string | ... 1 more ... | readonly string[])) | undefined; }' is not assignable to type 'Readonly<NumberFormatProps>'.
13:18:08 webpack.1 |       Types of property 'defaultValue' are incompatible.
13:18:08 webpack.1 |         Type 'string | number | readonly string[] | undefined' is not assignable to type 'string | number | undefined'.
13:18:08 webpack.1 |           Type 'readonly string[]' is not assignable to type 'string | number | undefined'.
13:18:08 webpack.1 |             Type 'readonly string[]' is not assignable to type 'string'.
13:18:08 webpack.1 |   Overload 2 of 2, '(props: NumberFormatProps, context: any): NumberFormat', gave the following error.
13:18:08 webpack.1 |     Type '{ accept?: string | undefined; alt?: string | undefined; autoComplete: string | undefined; autoFocus?: boolean | undefined; capture?: string | boolean | undefined; checked?: boolean | undefined; ... 286 more ...; value: (string & (string | ... 1 more ... | readonly string[])) | undefined; }' is not assignable to type 'Readonly<NumberFormatProps>'.
13:18:08 webpack.1 |       Types of property 'defaultValue' are incompatible.
13:18:08 webpack.1 |         Type 'string | number | readonly string[] | undefined' is not assignable to type 'string | number | undefined'.
13:18:08 webpack.1 |     19 | } & React.InputHTMLAttributes<HTMLInputElement>) => {
13:18:08 webpack.1 |     20 |   return (
13:18:08 webpack.1 |   > 21 |     <NumberFormat
13:18:08 webpack.1 |        |      ^^^^^^^^^^^^
13:18:08 webpack.1 |     22 |       thousandSeparator={true}
13:18:08 webpack.1 |     23 |       decimalScale={2}
13:18:08 webpack.1 |     24 |       allowNegative={false}
13:18:08 webpack.1 |  「wdm」: Failed to compile.

Right now I'm forced to pass them one by one:

<NumberFormat         
        thousandSeparator={true} 
        decimalScale={2}
        allowNegative={false}
        inputmode="numeric"
        
        // now this works fine
        demoProp={props.demoProp}
        onChange={() => props.onChange()}
        value={props.value.toString()}
      />

@s-yadav
Copy link
Owner

s-yadav commented Apr 16, 2021

From the error it looks like the type coming in props for defaultValue is different from what defined in NumberFormat.

We have a custom type for defaultValue.
https://github.com/s-yadav/react-number-format/blob/master/typings/number_format.d.ts#L6

and
https://github.com/s-yadav/react-number-format/blob/master/typings/number_format.d.ts#L42

@s-yadav
Copy link
Owner

s-yadav commented Apr 16, 2021

There is one PR related to this which will allow readonly string[] but haven't got any update on that.

#464

@alvarotrigo
Copy link
Author

alvarotrigo commented Apr 16, 2021

From the error it looks like the type coming in props for defaultValue is different from what defined in NumberFormat.

Yeah, but what I found strange is that I was not sending the defaultValue on my props.

I managed to make it work by filtering defaultValue and value from the props.

<PriceInput
        inputRef={inputRef}
        id="my_id"
        value={value}
        onChange={(e) => {
          //...
        }}
        maxLength={10}
        placeholder={5}
        disabled={false}
        autoComplete="off"
/>
export const PriceInput = ({
  inputRef,
  value,
  defaultValue,
  ...props
}: {
  value?: string;
  defaultValue?: string;
} & React.InputHTMLAttributes<HTMLInputElement>) => {
  return (
    <NumberFormat
      thousandSeparator={true}
      decimalScale={2}
      allowNegative={false}
      inputMode="numeric"
      customInput={CustomInput}
      value={value}
      {...props}
    />
  );
};

@s-yadav
Copy link
Owner

s-yadav commented Apr 16, 2021

I think this was because of how typescript infers the props object. If value and defaultValue is not filtered, it will try to match complete React.InputHTMLAttributes<HTMLInputElement> and NumberFormat type, finding a mismatch for a this types.

But when we extract it out, now typescript knows props is excluding defaultValue and value.

@alvarotrigo
Copy link
Author

I see, thanks!

@epashkov
Copy link

I have the same issue with Bootstrap FormControl

<NumberFormat
    name="price"
    value={price}
    data-test-id="price-input"
    decimalScale={0}
    onBlur={saveAndApply}
    thousandSeparator={' '}
    customInput={Form.Control}
    onKeyPress={handleKeyPress}
    onValueChange={values => {
        setValueIsChanged(values.floatValue !== price);
        setPrice(values.floatValue);
    }}
    placeholder={t('filter.placeholder.price')}
/>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants