react-textarea-autosize icon indicating copy to clipboard operation
react-textarea-autosize copied to clipboard

`style` prop type error

Open Haaxor1689 opened this issue 4 years ago • 11 comments

If I just try to pass text area attributes (from React.InputHTMLAttributes) to TextareaAutosize there is a type error that height property of style does not match.

type Props = React.InputHTMLAttributes<HTMLTextAreaElement>;
const Component: React.FC<Props> = props => <TextareaAutosize {...props} />;

Here is the full error:

Type '{ accept?: string | undefined; alt?: string | undefined; autoComplete?: string | undefined; autoFocus?: boolean | undefined; capture?: string | boolean | undefined; checked?: boolean | undefined; ... 279 more ...; css?: InterpolationWithTheme<...>; }' is not assignable to type 'Pick<TextareaAutosizeProps, "style" | "autoComplete" | "autoFocus" | "disabled" | "form" | "maxLength" | "minLength" | "name" | "placeholder" | "readOnly" | ... 262 more ... | "wrap">'.
  Types of property 'style' are incompatible.
    Type 'CSSProperties | undefined' is not assignable to type '(CSSProperties & Pick<CSSProperties, "height" | "width" | "translate" | "color" 
| "clipPath" | "filter" | "marker" | "mask" | "alignContent" | ... 753 more ... | "vectorEffect"> & { ...; }) | undefined'.
      Type 'CSSProperties' is not assignable to type 'CSSProperties & Pick<CSSProperties, "height" | "width" | "translate" | "color" | "clipPath" | "filter" | "marker" | "mask" | "alignContent" | ... 753 more ... | "vectorEffect"> & { ...; }'.
        Type 'CSSProperties' is not assignable to type '{ height?: number | undefined; }'.
          Types of property 'height' are incompatible.
            Type 'string | number | undefined' is not assignable to type 'number | undefined'.
              Type 'string' is not assignable to type 'number | undefined'.  TS2322

I don't feel like I should be getting an error there.

Haaxor1689 avatar Jun 01 '20 13:06 Haaxor1689

Why would you like to use props.style.height? This is being controlled by the react-textarea-autosize because it's the only way to implement "autosizing". I don't believe that you should ever pass this to this component, apart from providing an initial value when SSRing.

Andarist avatar Jun 02 '20 14:06 Andarist

I don't want to use it but when I pass textarea props to my wrapping components I get errors. Shouldn't then the better solution be to omit heigth prop as well and also export the props type so typescript users that make wrapping components can just use the exported type for passing down the props? I'll make those changes to my PR.

Haaxor1689 avatar Jun 03 '20 07:06 Haaxor1689

If I use the TextareaAutosizeProps instead of React.InputHTMLAttributes<HTMLTextAreaElement> I get error on ref attribute not matching. Here is full error:

Type '{ css: (theme: { colors: { primary: string; primaryLight: string; secondary: string; text: string; textLight: string; error: string; success: string; warning: string; lightGrey: string; darkerGrey: string; lightGreen: string; darkGreen: string; }; breakpoints: string[]; fontSizes: number[]; space: number[]; }) => Se...' is not assignable to type 'RefAttributes<HTMLTextAreaElement>'.
  Types of property 'ref' are incompatible.
    Type 'string | ((instance: HTMLTextAreaElement | null) => void) | RefObject<HTMLTextAreaElement> | null | undefined' is not assignable to type '((instance: HTMLTextAreaElement | null) => void) | RefObject<HTMLTextAreaElement> | null | undefined'.
      Type 'string' is not assignable to type '((instance: HTMLTextAreaElement | null) => void) | RefObject<HTMLTextAreaElement> | null | undefined'.  TS2322

With React.InputHTMLAttributes<HTMLTextAreaElement> the error isn`t there.

Haaxor1689 avatar Jun 03 '20 08:06 Haaxor1689

Could you prepare a repro case on which I could take a loot at?

Andarist avatar Jun 03 '20 10:06 Andarist

https://codesandbox.io/s/react-typescript-playground-ebgce?file=/src/index.tsx

Here are all three examples of just making a wrapper component that passes it's props down to TextareaAutosize component.

Haaxor1689 avatar Jun 03 '20 11:06 Haaxor1689

Just a note - I've recognized a problem on CodeSandbox using your provided repro https://github.com/codesandbox/codesandbox-client/issues/4307

I've also checked that those 2 are not the same:

type Ref1 = React.ComponentProps<typeof TextareaAutosize>["ref"]
type Ref2 = TextareaAutosizeProps["ref"]

I guess I need to export TextareaAutosizeProps differently (using the Ref1 approach), because when I've experimented with it that has caused this to work.

Andarist avatar Jun 03 '20 16:06 Andarist

Actually - I have gone in a slightly different direction. You can take a look at https://github.com/Andarist/react-textarea-autosize/commit/db872f035e8c033eb96c40eead9c041ec6b2e09f . I will probably release this over the weekend.

Andarist avatar Jun 03 '20 16:06 Andarist

I'm not exactly sure why JSX.IntrinsicElements['textarea'] and React.TextareaHTMLAttributes<HTMLTextAreaElement> use different ref types and quick google search did not return any answer on what is the exact difference between the two. I've chosen same approach as you in my code, just omitting ref because I'm not using it anyways.

Haaxor1689 avatar Jun 03 '20 17:06 Haaxor1689

I'm not exactly sure why JSX.IntrinsicElements['textarea'] and React.TextareaHTMLAttributes<HTMLTextAreaElement> use different ref types

I don't think this is a problem. The problem is that I've declared our props to use JSX.IntrinsicElements['textarea'] which allows for all kind of refs (ref object, function, legacy string), but TextareaAutosize is using React.forwardRef which is not allowing legacy string refs and thus you couldn't just spread TextareaAutosizeProps onto it.

But as ref never really appears as part of the props (it is received as a second argument within React.forwardRef) the solution was to just omit it from there.

Andarist avatar Jun 03 '20 17:06 Andarist

Can't you then just use the React.TextareaHTMLAttributes<HTMLTextAreaElement>?

Haaxor1689 avatar Jun 03 '20 17:06 Haaxor1689

Yes, I can. Thanks for the tip - this is even better. It seems that I have been using JSX.IntrinsicElements incorrectly all this time. TIL.

I've just prepared a change for this: https://github.com/Andarist/react-textarea-autosize/commit/61ca826a3fbe33abb9c67885d5bbd7b34ecd66db

Andarist avatar Jun 04 '20 11:06 Andarist