DEV Community

Chris Frewin
Chris Frewin

Posted on

React with TypeScript: Optional Props with Default Values

Straight to the Code

There's an example repository scaffolded with create-react-app which I've created for this post. Probably of most interest is the component FancyTitle which uses the default props pattern discussed in this blog post.

Now let's get into the details of the pattern.

Optional Props Pattern

When using TypeScript with React, it's easy enough to define optional props. With your props interface, you simply apply the optional parameter symbol ?:

interface IMyComponentRequiredProps {
  someRequiredProp: string;
  someOptionalProp?: string;
}
Enter fullscreen mode Exit fullscreen mode

Optional Props with Default Values Pattern

But what if we want default values for our optional props in the case when they are not specified?

A rather elegant way to do it is to define two separate interfaces, one for the required props, and one for the optional props. For example, if our component is called MyComponent:

// Required props
interface IMyComponentRequiredProps {

}

// Optional props
interface IMyComponentOptionalProps {

}
Enter fullscreen mode Exit fullscreen mode

We can then use the TypeScript extends operator to combine these two interfaces to the final props interface we would use to actually type the props parameter:

interface IMyComponentProps
  extends IMyComponentRequiredProps,
    IMyComponentOptionalProps {}
Enter fullscreen mode Exit fullscreen mode

We can then define our default props values by only taking the IMyComponentOptionalProps:

const defaultProps: IMyComponentOptionalProps = {
  color: "red",
  fontSize: 40,
};
Enter fullscreen mode Exit fullscreen mode

and then being sure to set these defaultProps to the component's defaultProps:

MyComponent.defaultProps = defaultProps;
Enter fullscreen mode Exit fullscreen mode

All Together Now...

Let's see this pattern in an actual React component. Here's the example component FancyTitle from the example repository which renders a customizable <h1> tag. The component has a required title string, and then a few optional style options. We can leverage the pattern discussed in the post to build the following:

import * as React from "react";

// Required props
interface IFancyTitleRequiredProps {
  title: string;
}

// Optional props
interface IFancyTitleOptionalProps {
  color: string;
  fontSize: number;
}

// Combine required and optional props to build the full prop interface
interface IFancyTitleProps
  extends IFancyTitleRequiredProps,
    IFancyTitleOptionalProps {}

// Use the optional prop interface to define the default props
const defaultProps: IFancyTitleOptionalProps = {
  color: "red",
  fontSize: 40,
};

// Use the full props within the actual component
const FancyTitle = (props: IFancyTitleProps) => {
  const { title, color, fontSize } = props;
  return <h1 style={{ color, fontSize }}>{title}</h1>;
};

// Be sure to set the default props
FancyTitle.defaultProps = defaultProps;

export default FancyTitle;
Enter fullscreen mode Exit fullscreen mode

That's it! Required, optional, and default values for props in a React functional component with TypeScript!

Thanks!

I hope you enjoyed this post and you find this pattern useful.

Cheers 🍺

-Chris

Top comments (3)

Collapse
 
ahmednour1979 profile image
AhmedNour1979 • Edited

I applied a different approach to resolve this issue by using a class, it works perfectly fine with me, what do you think about it?


class properties{
    myvariable?:string;
    myvisiability?:boolean;
    constructor()
    {
        this.myvariable="set inside Cosntructor";
        this.myvisiability=true;
    }
}

export default function LeftPanel(m_prop:properties)
{
    console.log("left panel var :" + m_prop.myvariable)
    if(m_prop.myvariable === undefined &&
         m_prop.myvisiability=== undefined)
    {
        const temp=new properties();
        m_prop=temp;
    }
    console.log("left panel var :" + m_prop.myvariable)
    return(
        <div >
            <h1> {"LeftPanel : " + m_prop.myvariable}</h1>
        </div>
    );
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
olivertembo profile image
olivertembo

What about this?
interface Props{
name: string;
middleName?: string;
}

const MyName = ({
name = John,
middleName = "",
}: Props) => {

What is wrong with the optional parameter?

Collapse
 
thesameeric profile image
Eric O Okiti

Personally, I feel this is recommended aproach nowadays since support for defaultProps is deprecated.