2

Let's say we have a component Foo that renders props.children and another component Bar. Both modules export a props interface.

Is there a way to enforce that Foo's children can be only of type Bar?

Ideally we could accomplish this with TypeScript at build-time.

Example:

import { createElement, FC, ReactNode } from 'react';
import { Bar, BarProps } from '../Bar';

export interface FooProps {
  children?: ReactNode; // this works
  // children?: ReactNode<BarProps>; // nope
  // children?: Bar; // nope
}

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

Note: we are not using PropTypes

2
  • Out of curiosity, why do you need a strong requirement on props.children? Commented Jul 1, 2020 at 14:34
  • Our internal component library needs to abide by a fairly strict UX specification/design guide. A contrived example would be that Table shouldn't be allowed to be a child of a Dropdown component. Commented Jul 1, 2020 at 14:46

1 Answer 1

0

Try this (reference)

export interface FooProps {
  children?: React.ReactElement<BarProps> | React.ReactElement<BarProps>[]
}
Sign up to request clarification or add additional context in comments.

4 Comments

I think you meant React.ReactElement<BarProps>[]?
If the children of Foo need to be completely strict to accepting a component with the type signature of Bar this will not work. Try rendering a simple h1 element as children to Foo (<Foo><h1>Hello</h1></Foo>) and you will see that the compiler doesn't even complain.
I tried this out, and I'm still able to pass non-Bar components in as children of Foo with no compiler warnings/errors
If you read further in the reference above you'll see "Will get rid of the error, but it won't be type-checking the children properly", I think this is the closest you will get for restricting in the FooProps interface. Maybe throw an error or filter wrong types at the beginning of your component will do the trick?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.