Search code examples
reactjstypescriptreact-typescript

How to pass an interface as a prop in React w/ TypeScript?


I'd like to pass an object into my functional component. This object has a consistent formatting so I'm using an interface. Here's the functional component parameters line:

interface Option { value: any, label: string; } 

export default function JSelect(options: Option[], primaryColor: string, textColor: string) {

and here's the usage of the component:

interface Option { value: any, label: string; }
const letteroptions: Option[] = [
    { value: 0, label: 'Ab' },
    { value: 1, label: 'A' },
    { value: 2, label: 'Bb' },
    { value: 3, label: 'B' },
    { value: 4, label: 'C' },
    { value: 5, label: 'Db' },
    { value: 6, label: 'D' },
    { value: 7, label: 'Eb' },
    { value: 8, label: 'E' },
    { value: 9, label: 'F' },
    { value: 10, label: 'Gb' },
    { value: 11, label: 'G' }
];

<JSelect options={letteroptions} primaryColor='#87c6bb' textColor='#2c3f43' />

The types are defined exactly the same, so I'm unsure why this isn't working. Here's the error I get:

(property) options: Option[]

Type '{ options: Option[]; primaryColor: string; textColor: string; }' is not assignable to type 'IntrinsicAttributes & Option[]'. Property 'options' does not exist on type 'IntrinsicAttributes & Option[]'.ts(2322)


Solution

  • export default function JSelect(options: Option[], primaryColor: string, textColor: string) {
    

    If JSelect is a component, then components only receive one argument, not multiple. That argument is an object with the individual props. So the type for this should be:

    interface JSelectProps {
      options: Option[],
      primaryColor: string,
      textColor: string
    }
    
    export default function JSelect(props: JSelectProps) {
      // ... do stuff with props.options, props.primaryColor, props.textColor
    }
    

    If you wish, you can use destructuring to break the props object up into individual variables:

    export default function JSelect({ options, primaryColor, textColor }: JSelectProps) {
      // ... do stuff with options, primaryColor, textColor
    }