P Varga
P Varga

Reputation: 20269

Type for a React component with certain props

I would like to express the type of a component that takes certain props:

Just as an example, I would like to render anything that accepts an ISIN and a rate:

type Props = {
  Item: TheQuestion;
  data: {ISIN: string, ...};
}
function Renderer({Item, data}: Props) {
  return <foo>
    <bar />
    <Item ISIN={data.ISIN} rate={80/64} />
  </foo>;
}

How could I write the type I called TheQuestion here?

One thing that kind of works is React.FunctionComponent<{ISIN: string, rate: number}>, but this only allows function components, not class-based ones.

Is there a generic type that accommodates both?

Upvotes: 0

Views: 70

Answers (1)

subashMahapatra
subashMahapatra

Reputation: 6857

Yes, React.ComponentType. Here is what type definition for it looks like. It takes a generic type argument for props.

type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;

For your use case this is what the implementation might look like,

import React, { FC, ComponentType } from 'react';

type Props = {
  Item: ComponentType<{ ISIN: string; rate: number }>;
  data: { ISIN: string, /* other types... */ };
};

function Renderer({ Item, data }: Props) {
  return (
    <Foo>
      <Bar />
      <Item ISIN={data.ISIN} rate={80 / 64} />
    </Foo>
  );
}

const Foo: FC = ({ children }) => {
  return <div>{children}</div>;
};

const Bar: FC = () => {
  return <div>Hello</div>;
};

P.S.- I suggest moving the type argument passed to another interface because it could be reused somewhere else. Of course, you can tweak it depending on your application,

interface ItemProps {
  ISIN: string;
  rate: number;
}

type ItemComponent = ComponentType<ItemProps>

// for the renderer
type Props = {
  Item: ItemComponent;
  // rest
}

Upvotes: 1

Related Questions