admin管理员组文章数量:1200962
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 | );
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>
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 | );
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>
Share
Improve this question
asked Dec 27, 2019 at 0:54
LiondancerLiondancer
16.5k54 gold badges163 silver badges262 bronze badges
4 Answers
Reset to default 12Using type React.ComponentProps<'button'>)
for Button component worked for me.
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.
You can create your custom reusable component something like this, where you can pass your custom props and as well receive all the button props using ...rest. And now when you use this component you can just simply pass the onClick and even if you now don't specify this prop it will automatically get it, as it can infer all the default button elements props.
The cn is for className, it is a util function that helps us pass new classNames and overwrite the existing ones that makes it more reusable component.
import React from "react";
import { cn } from "@/lib/utils/twMerge";
interface ButtonProps extends
React.ButtonHTMLAttributes<HTMLButtonElement> {
className?: string;
children: React.ReactNode;
}
const Button = (props: ButtonProps) => {
const { className, children, ...rest } = props;
return (
<button
className={cn(
"rounded-[20px] bg-accent-green min-h-[50px] text-[#000000]
text-[16px] font-normal font-poppins flex items-center
justify-center min-w-[160px] ",
className
)}
{...rest}
>
{children}
</button>
);
};
export default Button;
Usage:
Here's how you can import/use and pass the type and onClick props without specifying these inside the custom Button Component.
import Button from "@/components/ui/Button";
<Button type="submit" onClick={()=>console.log("Clicked")}>
Get started
</Button>
Here's how you can create the cn function. It is using two packages "tailwind-merge" and "clsx", so if you want to use this then make sure you install them as well and also create this function like this.
import { twMerge } from "tailwind-merge";
import { clsx, ClassValue } from "clsx";
export const cn = (...inputs: ClassValue[]) => {
return twMerge(clsx(inputs));
};
Typescript has got type definitions. This also applies to html elements such as buttons, inputs etc. If a reusable component is to be created, e.g "A button component" the type or interface needs to match what has been defined by typescript.
Quick fix in a few lines using an interface for a button element; The button types defined below are the same with what had be defined by typescript.
import React from 'react';
interface IProps {
text: string,
type: "button"|"submit"|"reset"|undefined
}
const Button = ({ text, ...otherProps }: IProps) => (
<button {...otherProps}>
{ text }
</button>
);
export default Button;
This should fix the error message "Typescript with not assignable type error"
本文标签:
版权声明:本文标题:javascript - Creating reusable Button Component with React and Typescript with not assignable type error - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738582369a2101239.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论