admin管理员组

文章数量:1221398

function Foo({
  children,
  ...rest
}: {
  children: React.ReactNode;
  /*rest: how do I type `rest`? */
}) {
  return (
    <span style={{ background: "red" }} {...rest}>
      {children}
    </span>
  );
}

export default function App() {
  return (
    <div className="App">
      <Foo style={{ background: "blue" }}>Hello CodeSandbox</Foo>
    </div>
  );
}

Here is the demo: =/src/App.tsx:50-412

Foo is used to override the props that span accepts. How do I type rest in Foo?

function Foo({
  children,
  ...rest
}: {
  children: React.ReactNode;
  /*rest: how do I type `rest`? */
}) {
  return (
    <span style={{ background: "red" }} {...rest}>
      {children}
    </span>
  );
}

export default function App() {
  return (
    <div className="App">
      <Foo style={{ background: "blue" }}>Hello CodeSandbox</Foo>
    </div>
  );
}

Here is the demo: https://codesandbox.io/s/how-to-type-rest-huv2z?file=/src/App.tsx:50-412

Foo is used to override the props that span accepts. How do I type rest in Foo?

Share Improve this question asked Feb 9, 2022 at 7:08 JojiJoji 5,62510 gold badges56 silver badges116 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 9

You can't type the spread portion of the object directly, but you can add the necessary properties with the union type (&).

In this case, the extra properties you want to allow are of type React.HTMLAttributes<HTMLSpanElement>. So you end up with:

function Foo({
  children,
  ...rest
}: {
  children: React.ReactNode;
} & React.HTMLAttributes<HTMLSpanElement>) {
  return (
    <span style={{ background: "red" }} {...rest}>
      {children}
    </span>
  );
}

As an aside, you can avoid manually typing the children property using the React.FunctionComponent type. This actually avoids the union definition and is a bit more idiomatic in React code.

const Foo: React.FunctionComponent<React.HTMLAttributes<HTMLSpanElement>> = ({
  children,
  ...rest
}) => {
  // ...
}

You can just use [x:string]: any; like

function Foo({
  children,
  ...rest
}: {
  children: React.ReactNode;
  [rest:string]: any;
}) {
  return (
    <span style={{ background: "red" }} {...rest}>
      {children}
    </span>
  );
}

export default function App() {
  return (
    <div className="App">
      <Foo style={{ background: "blue" }} id="example">Hello CodeSandbox</Foo>
    </div>
  );
}

You can use something like this as a type:

{
  children: React.ReactNode;
  /*rest: how do I type `rest`? */
} & HTMLProps<HTMLSpanElement>

本文标签: