reactjs - Ispravno proširenje svojstava komponente na zadana svojstva HTML gumba


Radim na komponenti gumba koja ima variant svojstvo za određivanje njegove boje. Evo pojednostavljene verzije

interface Props extends React.HTMLProps<HTMLButtonElement> {
  variant: 'yellow' | 'green';
}

function Button({ variant, ...props }: Props) {
  console.log(variant);

  return (
    <button
      type="button"
      {...props}
    />
  );
}

Dobivam TypeScript pogrešku ispod mog type koja kaže:

(JSX atribut) ButtonHTMLAttributes.type?: "button" | "submit" | "reset" | undefined Tip 'string' nije moguće dodijeliti tipu '"button" | "submit" | "reset" | undefined'.ts(2322) index.d.ts(1872, 9): Očekivani tip dolazi iz svojstva 'type' koje je deklarirano ovdje na tipu 'DetailedHTMLProps, HTMLButtonElement>'

Dakle, nisam siguran proširujem li svojstva gumba ispravno? Možda postoji neki drugi način?

Odgovor #1

Ažuriranje 2023

ako želite napraviti gumb bez ikakvih dodatnih stvari, možete proširiti React.ComponentPropsWithoutRef<"button"> a za ljude koji pokušavaju napraviti ponovno upotrebljivu komponentu, trebate forwardRef osnovnog elementa i tada možete koristiti ComponentPropsWithRef:

interface Props extends React.ComponentPropsWithoutRef<"button"> {
  variant: 'yellow' | 'green';
}

zašto ne koristiti React.HTMLAttributes<HTMLButtonElement>?

ovo se događa kada koristiš:

export interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
  /* etc */
}

function App() {
  // Property 'type' does not exist on type 'IntrinsicAttributes & ButtonProps'
  return <Button type="submit"> text </Button>;
}

Stari odgovori

Codesandbox Pregled Uživo

ono što vjerojatno tražite je React.HTMLAttributes<HTMLButtonElement>

import * as React from "react";
import { render } from "react-dom";

import "./styles.css";

interface Props extends React.HTMLAttributes<HTMLButtonElement> {
  variant: 'yellow' | 'green';
}

function Button({ variant, ...props }: Props) {

  return (
    <button
      type="button"
      {...props}
    />
  );
}

const rootElement = document.getElementById("root");
render(<Button variant='green' />, rootElement);

da bismo bili točniji, možemo koristiti React.ButtonHTMLAttributes<HTMLButtonElement>

import * as React from "react";
import { render } from "react-dom";

import "./styles.css";

interface Props extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant: 'yellow' | 'green';
}

function Button({ variant, ...props }: Props) {

  return (
    <button
      type="button"
      {...props}
    />
  );
}

const rootElement = document.getElementById("root");
render(<Button variant="green" />, rootElement);

Odgovor #2

Trebali biste koristiti ButtonHTMLAttributes umjesto HTMLProps ovako:

interface Props extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant: 'yellow' | 'green';
}

function Button({ variant, ...props }: Props) {
  console.log(variant);

  return (
    <button
      type="button"
      {...props}
    />
  );
}

Povezani članci