Skip to content

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Defining Props in React Function Component with Typescript

Aug 25, 2020 • 5 Minute Read

Introduction

This guide will provide you with the syntax you need to properly define the props entering your components, compare and contrast defining props as a class or interface type, and give you a helpful tip for when you need to provide default values to optional props.

Which Keyword Should I Use?

Typescript brings some awesome features that extend JavaScript in powerful ways, including the ability to define the structure of an object in a variety of ways. In your search for the best way to define objects, you will undoubtedly encounter a variety of options, class and interface being the most common. If you take a look at Typescript's documentation, you can research for yourself the difference between these common object definers. This guide will give you the short version.

class is for when you want to define more than just the structure of an object:

      class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}
let greeter = new Greeter('world')
    

interface is for when you want to enforce structural contracts (i.e what you want passed in or what you want returned back):

      interface FullName{
    firstName: string;
    lastName: number;
}

const fullNameObj:FullName = {
    firstName: "Jon",
    lastName: "Snow"
}
    

So which should you use to define a prop? If you said interface, you would be correct.

Defining Props

Whether you're coming in fresh to using Typescript with React or are a grizzled veteran looking to add more functional components to your codebase by introducing hooks, it's important to know the different ways to define props.

Simple Yet Effective

One of the ways you can define props is simply by defining them in the parameter list of a function as demonstrated above.

For example:

      interface FullName {
    firstName: string;
    lastName: string;
}
function FunctionalComponent(props:FullName){
    // props.firstName
    // props.lastName
}
    

A More Flexible Way

In most cases, the simple way is fine. But what if you want to define default props if they aren't passed in? Or you just want to have cleaner syntax within your component?

For those cases, you can leverage a JavaScript syntax feature known as destructuring. This allows more flexibility in how you can define your props.

      // Using the same FullName interface from the last example
function FunctionalComponent({firstName, lastName}:FullName){
    // firstName
   // lastName
}
    

What if you wanted to add a middle name? Not everyone has a middle name, so you want to make it optional. Destructuring can provide a clean solution to that problem.

      interface OptionalMiddleName {
    firstName: string;
    middleName?: string;
    lastName: string;
}
function Component({firstName, middleName = "N/A", lastName}:OptionalMiddleName){
    // If middleName wasn't passed in, value will be "N/A"
}
    

Now whenever you need to reference middleName, if it doesn't exist you get a nice default "N/A".

Accomplishing the same functionality using the non-destructured syntax would look something like this:

      // using the same OptionalMiddleName interface from above
function Component(props:OptionalMiddleName){
    if(!props.middleName){
        props.middleName = "N/A"
    }
}
    

Not awful, but not exactly nice either.

As always, though, beautiful code is in the eye of the beholder (sometimes).

Using React.FC

Another way to define props is to import and use React's Functional Component type, FC for short.

Using React.FC is more verbose, but does have some added benefits:.

  • Explicit with its return type
  • Provides type checking and autocomplete for static properties (i.e displayName, defaultProps)
  • Provides an implicit definition of children:
      const ReactFCComponent: React.FC<{title:string}> = ({children, title}) => {
        return <div title={title}>{children}</div>
    }
    

You can read more about the benefits of React.FC here

Which should you use? The React community generally frowns upon using React.FC due to its verbosity, and because its benefits aren't worth the trouble and difficulty to read.

Conclusion

Hopefully this simple guide provides you with a good reference for you to work from. In general I like to destructure all my props entering the component, as it provides a clean and effective syntax to work with. Good luck in your Typescript React journeys!

Learn More