Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating reusable Button Component with React and Typescript with not assignable type error

I am trying to create a reusable component in reactjs with typescript. I am currently getting this error:

Type '{ children: string; type: string; }' is not assignable to type 'DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>'.
  Type '{ children: string; type: string; }' is not assignable to type 'ButtonHTMLAttributes<HTMLButtonElement>'.
    Types of property 'type' are incompatible.
      Type 'string' is not assignable to type '"button" | "submit" | "reset" | undefined'.  TS2322

     7 | 
     8 | const Button = ({ text, ...otherProps }: IProps) => (
  >  9 |   <button {...otherProps}>
       |    ^
    10 |     { text }
    11 |   </button>
    12 | );

enter image description here

I am pretty new to typescript so I am not sure why I have this error. I think I am not assigning the correct types in my IProps interface in Button.tsx. I am not sure which type to assign

Button.tsx

import React from 'react';

interface IProps {
  text: string,
  type: string
}

const Button = ({ text, ...otherProps }: IProps) => (
  <button {...otherProps}>
    { text }
  </button>
);

export default Button;

How it is currently being used:

<Button type="submit">Sign up</Button>
like image 995
Liondancer Avatar asked Dec 27 '19 00:12

Liondancer


2 Answers

Typescript already has a definition of the types that are allowed in a button so you have to declare an enum which matches with the available types:

import React from 'react';

enum ButtonTypes {
  "button",
  "submit",
  "reset",
  undefined
} 

interface IProps {
  text: string,
  type: ButtonTypes
}

const Button = ({ text, ...otherProps }: IProps) => (
  <button {...otherProps}>
    { text }
  </button>
);

export default Button;

You can read more on enums here.

like image 137
Jose Felix Avatar answered Sep 30 '22 01:09

Jose Felix


Using type React.ComponentProps<'button'>) for Button component worked for me.

like image 39
sumi Avatar answered Sep 30 '22 02:09

sumi