1

The typescript compiler in VSCode, currently at TypeScript React 4.4.2 points to a TS(2339) error: Property 'Col' does not exist on type 'FC<GridProps>'.

I've tried adding this prop to GridProps:

export type GridProps = {
  children: ReactNode;
  className?: string;
  Col: JSX.Element;
};

But the error still shows. I think this is because the Grid component is not initialized. I've seen this convention of extending a main component with other uninitialized components such as Grid.Col = Col (see the screenshot), and it actually works when it is implemented:

<Grid.Col>
  {/* */}
</Grid.Col>

How to remove the TS(2339) error in this case?

NOTE: I've seen components like these before, the compiler doesn't throw and they don't event specify the Component prop in their prop types.

screenshot that describes the error

enter image description here

1 Answer 1

1

First, you need to remove Col in GridProps, Col is not a prop.

export type GridProps = {
  children: ReactNode;
  className?: string;
};

Second, to make TS happy, we need to specify the type of Grid component.

export type GridType = FC<GridProps> & {
  Col: FC<{}>;
};

And the implementation:

export const Grid: GridType = (({ className, children }) => {
  return <div className={className}>{children}</div>;
}) as GridType;

Grid.Col = () => {
  return <p>hello</p>;
};

Demo here:

https://codesandbox.io/s/practical-haze-w3o57?file=/src/App.tsx

Another approach is, using Function, not Arrow Function with React.FC<>.

export type GridProps = {
  children: ReactNode;
  className?: string;
};

export function Grid({ className, children }: GridProps) {
  return <div className={className}>{children}</div>;
}

Grid.Col = () => {
  return <p>hello</p>;
};

https://codesandbox.io/s/optimistic-pike-1ir9i?file=/src/App.tsx

Another approach is, not to use React.FC. You can read more about this here: TypeScript React.FC<Props> confusion

export type GridProps = {
  children: ReactNode;
  className?: string;
};

export const Grid = ({ className, children }: GridProps) => {
  return <div className={className}>{children}</div>;
};

Grid.Col = () => {
  return <p>hello</p>;
};

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <Grid>
        <Grid.Col />
      </Grid>
    </div>
  );
}
3
  • Genius! If Col is not a prop, then what is it? Technically speaking. Also, what's the difference between the approach with an arrow function and a function?
    – Gus
    Commented Sep 16, 2021 at 4:49
  • you can think a function is an object (in JS function is a first-class object). so you can add a property to this object. but technically, props is a function argument. therefore Col is property of the object, not a property of the props object. By defined as an arrow function with FC<GridProps>, TypeScript will understand strictly than a normal function.
    – Tiep Phan
    Commented Sep 16, 2021 at 8:42
  • 1
    I just updated my anwser with an example of a functional component without React.FC
    – Tiep Phan
    Commented Sep 16, 2021 at 8:50

Not the answer you're looking for? Browse other questions tagged or ask your own question.