Best practice Typescript and React

Viewed 117

I have a specific question around a component that receives {...props} to allow for any prop to be passed in. This component only receives a string prop right now, but when it was written it wanted to allow for basically any prop to be passed in. What is the best typescript best practice to tackle this? Since you don't know what prop may be passed in? Do you only handle the specifc prop ? or is there a way for typescript to allow for ...props?

TY team :D

1 Answers

Here is the best practice, as far as I know.

Let's assume your component is called ShowAnyProps, and it takes any props, and you don't want to enforce any limitations on what kind of props can be passed.

The ShowAnyProps Component

type IProps = Record<string, unknown>;
export const ShowAnyProps: React.FC<IProps> (props) {
    // Use props here...
}

props is an object with string keys, but you don't know its values. Object keys are always strings, and props is always an object, because that's how JSX works.

Inside the component, you'll want to do some type narrowing to handle all possible kinds of values:

  • string
  • number
    • NaN
  • boolean
  • null
  • undefined
  • object (and other things that are objects):
    • array
    • function
    • class instances
  • Symbol
  • bigint
  • Map
  • Set

Given the wide variation of things that can be passed in, you might want to limit the props, to only "regular" values. Maybe JSON-like values only:

import type { JSONValue } from 'type-fest';
type IProps = Record<string, JsonValue>;

Usage of ShowAnyProps

Material-UI has a good convention. Instead of passing all props to the component, the intended props are passed on a sub-object. See inputProps on TextField, for example.

So the usage would look like this:

interface IProps {
    // own props
    showAnyPropsProps: Record<string, JsonValue>;
};
export const UsageComponent: React.FC<IProps> (props) {
    // ...
    return (
        <div>
            {/* ... other stuff ... */}
            <ShowAnyProps {...props.showAnyPropsProps} />
        </div>
    );
}
Related