DEV Community

Cover image for How to define types in React Typescript
Bayu Setiawan
Bayu Setiawan

Posted on

How to define types in React Typescript

By leveraging TypeScript's type annotations, interfaces, and generics, you can establish strong type contracts within your React components.
Here's how to define types effectively in various scenarios:

  • Props
type GreetProps = {
  name: string;
  messageCount?: number;
  isLoggedIn: boolean;
};

export default function Greet(props: GreetProps) {
  const { messageCount = 0, name, isLoggedIn } = props;
  return (
    <div>
      <h1>
        {isLoggedIn
          ? `Welcome ${name}, you have ${messageCount} unread message`
          : `Welcome Guest`}
      </h1>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode
  • Union
type StatusProps = {
  status: 'loading' | 'success' | 'error';
};

export default function Status({ status }: StatusProps) {
  let message;
  if (status === 'loading') {
    message = 'Loading...';
  } else if (status === 'success') {
    message = 'Data fetched successfully';
  } else if (status === 'error') {
    message = 'Error fetching data';
  }

  return (
    <div>
      <h2>Status - {message}</h2>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode
  • Children
type HeadingProps = {
  children: string;
};

export default function Heading({ children }: HeadingProps) {
  return <h1>{children}</h1>;
}

Enter fullscreen mode Exit fullscreen mode
  • Children (element)
type OscarProps = {
  children: React.ReactNode;
};
export default function Oscar({ children }: OscarProps) {
  return <div>{children}</div>;
}

Enter fullscreen mode Exit fullscreen mode
  • Event: onClick()
type ButtonProps = {
  handleClick: (event: React.MouseEvent<HTMLButtonElement>, id: number) => void;
};

export default function Button(props: ButtonProps) {
  return (
    <button
      onClick={(event) => props.handleClick(event, 1)}
      className="btn-secondary"
    >
      Click
    </button>
  );
}

Enter fullscreen mode Exit fullscreen mode
  • Event: onChange()
type InputProps = {
  value: string;
  handleChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
};

export default function Input({ value, handleChange }: InputProps) {
  return <input type="text" value={value} onChange={handleChange} />;
}

Enter fullscreen mode Exit fullscreen mode
  • Styles
type ContainerProps = {
  styles: React.CSSProperties;
};

export default function Container(props: ContainerProps) {
  return <div style={props.styles}>Container</div>;
}

Enter fullscreen mode Exit fullscreen mode
  • State
import { useState } from 'react';

type AuthUser = {
  name: string;
  email: string;
};

export default function User() {
  const [user, setUser] = useState<AuthUser>({} as AuthUser);

  const handleLogin = () => {
    setUser({
      name: 'bayu',
      email: 'bayu@gmail.com',
    });
  };
  const handleLogout = () => {
    setUser({} as AuthUser);
  };
  return (
    <div>
      <button className="btn-primary mr-3" onClick={handleLogin}>
        Login
      </button>
      <button className="btn-info" onClick={handleLogout}>
        Logout
      </button>
      <h3>User name is {user.name}</h3>
      <h3>User email is {user.email}</h3>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode
  • Reducer
import { useReducer } from 'react';

const initialState = {
  count: 0,
};

type CounterState = {
  count: number;
};

type CounterAction = {
  type: string;
  payload: number;
};

function reducer(state: CounterState, action: CounterAction) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + action.payload };
    case 'decrement':
      return { count: state.count - action.payload };
    default:
      return state;
  }
}

export default function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button
        onClick={() => dispatch({ type: 'increment', payload: 1 })}
        className="btn-primary"
      >
        Increment
      </button>
      <button
        onClick={() => dispatch({ type: 'decrement', payload: 1 })}
        className="btn-secondary"
      >
        Decrement
      </button>
    </>
  );
}

Enter fullscreen mode Exit fullscreen mode

Incorporating TypeScript type definitions into your React projects revolutionizes the way you build and maintain user interfaces. By precisely annotating prop types, state types, context types, and even custom hooks, you're able to catch errors early, improve code documentation, and make collaboration smoother.

This blog post has illuminated the significance of type definitions in React TypeScript development and provided practical examples for different scenarios. With these techniques, you're well-equipped to create more predictable and robust React applications, ultimately delivering a better user experience and accelerating your development process.

Hope this helps!

Top comments (1)

Collapse
 
codebayu profile image
Bayu Setiawan

Hi, kindly leave a like and comment if you got new insight! 🔥