Skip to main content
Props allow you to pass data from parent components to child components. TypeScript interfaces help ensure type safety.

Defining Props with Interfaces

Use TypeScript interfaces to define the shape of your component’s props:
interface Props {
  name: string;
  quantity?: number;
}
The ? makes quantity optional, meaning the component can be used with or without it.

Using Props in Components

Destruct props in the function parameters and add the interface type:
import { useState } from "react";
import cesese from './ItemCounter.module.css';

interface Props {
  name: string;
  quantity?: number;
}

export const ItemCounter = ({ name, quantity }: Props) => {
  const [count, setCount] = useState(Number);

  const handleAdd = () => {
    setCount(count + 1);
  };

  const handleSub = () => {
    if (count === 0) return;
    setCount(count - 1);
  };

  return (
    <section className={cesese['item-row']}>
      <span 
        className="item-text"
        style={{
          color: count === 0 ? 'red' : 'black',
        }}
      >
        {name}
      </span>
      <button onClick={handleAdd}>+1</button>
      <span>{count}</span>
      <button onClick={handleSub}>-1</button>
    </section>
  );
};

Passing Props to Components

Pass props as attributes when rendering components:
<ItemCounter name="Nintendo xdnt" quantity={2} />
<ItemCounter name="exbox" quantity={0} />
<ItemCounter name="nuse xddddd equisde" quantity={10} />
String props use quotes, while numbers and other JavaScript values use curly braces.

Props in Lists

When rendering components from an array, props are passed from the mapped data:
interface ItemInCart {
  productName: string;
  quantity: number;
}

const itemsInCart: ItemInCart[] = [
  { productName: 'Nintendo swtich2xdd', quantity: 10 },
  { productName: 'exbos', quantity: 0 },
  { productName: 'diyin light 3 :000', quantity: 2 },
];

export function FirstSteps() {
  return (
    <>
      <h1>Carrito de compras</h1>

      {itemsInCart.map(({ productName, quantity }) => (
        <ItemCounter 
          key={productName} 
          name={productName} 
          quantity={quantity}
        />
      ))}
    </>
  );
}

Best Practices

1

Always define interfaces

Create TypeScript interfaces for all component props to catch errors early.
2

Use optional props wisely

Mark props as optional with ? when they have default behavior or aren’t always needed.
3

Destruct props

Destruct props in the function parameters for cleaner code: ({ name, quantity }: Props).
4

Keep props simple

Pass primitive values when possible. For complex data, consider breaking into multiple props.

Required vs Optional Props

interface Props {
  name: string;      // Required - must be provided
  quantity?: number; // Optional - can be omitted
}
When a prop is optional, make sure your component handles the case where it’s undefined.

Type Safety Benefits

TypeScript will catch errors at compile time:
// ✅ Correct
<ItemCounter name="Product" quantity={5} />

// ✅ Also correct (quantity is optional)
<ItemCounter name="Product" />

// ❌ Error: missing required prop 'name'
<ItemCounter quantity={5} />

// ❌ Error: quantity should be a number
<ItemCounter name="Product" quantity="5" />
Enable strict mode in your tsconfig.json to get the most out of TypeScript’s type checking.

Build docs developers (and LLMs) love