0

I'm trying to ensure that the component passed to another component as a prop (i.e. <Foo Component={Bar} />) is declared with the correct props.

This works fine when the component being passed in has props defined. However, if there are no props defined, TypeScript doesn't throw an error.

Here's an example:

import { ComponentType } from 'react';

type A = {
  foo: string;
}

type B = {
  Component: ComponentType<A>;
}

const Test = ({ Component }: B) => (
  <Component foo="test" />
);

const NoProps = () => <div />;
const CorrectProps = ({ foo }) => <div />;
const IncorrectProps = ({ bar }) => <div />;

// does not error - but it should?
const C = () => <Test Component={NoProps} />;

// no error as expected
const D = () => <Test Component={CorrectProps} />;

// errors as expected
const E = () => <Test Component={IncorrectProps} />;

I was wondering if it is possible to enforce the correct props to be defined?

1 Answer 1

1

This is more a quirk of functions.

In javascript it raises no errors to provide more arguments than a function accepts. And typescript agrees.

For example:

type Fn = (arg: number) => number
const fn: Fn = () => 123 // this is fine
fn(999) // 123

See playground

This feature is really handy and used a lot. For example in a react onClick callback:

onClick={() => doStuff()} // no arg
onClick={(event) => doStuffWithEvent(event)} // with arg

That works because typescript allows you pass a function of fewer arguments to a function type expects more arguments. And it's pretty nice that we don't get an error in the first case where the argument is omitted. In general, it's better to omit the argument than to declare it and not use it.


So since functional components are just functions, the same rules apply. Remember that the <Component> angle brace syntax is just syntax sugar for calling your functions.

So:

<Component foo='test' />

Will end up calling:

Component({ foo: 'test' })

And if Component happens to be a function type that accepts no arguments, then no type error is raised because nothing bad will happen.

The reason that you do get an error here:

// errors as expected
const E = () => <Test Component={IncorrectProps} />;

Is that now you are passing in a function that takes one argument, and the type of that argument is actually wrong. This means your component requires a prop that Test will not pass to it, which will likely cause a crash.

So, in general, I don't think there's any harm in allowing you to pass a component that takes no props, and Typescript seems to agree.

Sign up to request clarification or add additional context in comments.

Comments

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.