Home > Back-end >  React Typescript: Naming a component's property as "type" causes Typescript to thro
React Typescript: Naming a component's property as "type" causes Typescript to thro

Time:12-04

I am running into an issue where typescript will not allow me to name a property type

This fails:

import "./styles.css";
import styled from "styled-components";

enum BUTTON_TYPES {
  BUTTON = "button",
  SUBMIT = "submit"
}

interface ButtonProps {
  type: BUTTON_TYPES; // <------------------------ this
}

const Button = styled.button<ButtonProps>``;

export default function App() {
  return (
    <div className="App">
      <Button type={BUTTON_TYPES.BUTTON}>hey</Button>
    </div>
  );
}

However, if I rename type to foobar, it works perfectly fine

import "./styles.css";
import styled from "styled-components";

enum BUTTON_TYPES {
  BUTTON = "button",
  SUBMIT = "submit"
}

interface ButtonProps {
  foobar: BUTTON_TYPES; // <------------------------ this
}

const Button = styled.button<ButtonProps>``;

export default function App() {
  return (
    <div className="App">
      <Button foobar={BUTTON_TYPES.BUTTON}>hey</Button>
    </div>
  );
}

https://codesandbox.io/s/charming-borg-hl2x6?file=/src/App.tsx

CodePudding user response:

The TS error that you are getting is because of the fact your are trying to override native HTML attribute type. This prop is locked to "button" | "submit" | "reset" | undefined if you take a look at the type definition.
This also seems to be a problem with styled-components since they break native attributes with matching props.

Aside from the fact that TS prevents you to do this, I think that this way of creating component might be an anti-pattern.

What i would suggest to you, if you want to have type with HTML type for button element you can do something like this. With this you can forward type attribute to be prop your custom Button component to others to use:

import React, { FunctionComponent } from 'react'
import styled from "styled-components";

import "./styles.css";

interface ButtonProps{
  type: React.ButtonHTMLAttributes<any>['type'];
}

const ButtonStyled = styled.button`
  color: pink;
`;

const Button : FunctionComponent<ButtonProps>= ({type, children}) => 
  <ButtonStyled type={type}>{children}</ButtonStyled>


export default function App() {
  return (
    <div className="App">
      <Button type='button'>hey</Button>
    </div>
  );
}

Codesanbox: https://codesandbox.io/s/button-type-attribute-m1i3u

NOTE:
This may not be what you were looking for, as you want to have enum available to assign to type prop, but as i said, i think your way clashes with pattern of wrapping native HTML elements with a custom React component.

CodePudding user response:

This is not a problem with TypeScript. HTML button tag already has a property type that accepts button, reset or submit as a value.

Reference: https://www.w3schools.com/tags/tag_button.asp

  • Related