Skip to main content

Type Definition

type IconType = (props: IconBaseProps) => React.ReactNode;

Overview

IconType is a TypeScript type alias that represents the signature of all icon components in React Icons. It defines a function that accepts IconBaseProps and returns a React.ReactNode. This type is used throughout the library to ensure type safety when working with icon components, particularly useful when passing icons as props, storing them in arrays, or creating wrapper components.

Usage

Type Signature

type IconType = (props: IconBaseProps) => React.ReactNode
Parameters:
  • props - An object conforming to the IconBaseProps interface
Returns:
  • React.ReactNode - The rendered icon element

Common Use Cases

1. Icon as Component Prop

import { IconType } from 'react-icons';
import { FaBeer, FaCoffee, FaPizza } from 'react-icons/fa';

interface CardProps {
  title: string;
  icon: IconType;
}

function Card({ title, icon: Icon }: CardProps) {
  return (
    <div className="card">
      <Icon size={24} color="blue" />
      <h3>{title}</h3>
    </div>
  );
}

// Usage
<Card title="Beverages" icon={FaBeer} />
<Card title="Drinks" icon={FaCoffee} />

2. Array of Icons

import { IconType } from 'react-icons';
import { FaHome, FaUser, FaCog, FaBell } from 'react-icons/fa';

const navigationIcons: IconType[] = [
  FaHome,
  FaUser,
  FaCog,
  FaBell
];

function Navigation() {
  return (
    <nav>
      {navigationIcons.map((Icon, index) => (
        <Icon key={index} size={20} />
      ))}
    </nav>
  );
}

3. Icon Map/Dictionary

import { IconType } from 'react-icons';
import { FaCheckCircle, FaExclamationTriangle, FaInfoCircle, FaTimesCircle } from 'react-icons/fa';

type AlertType = 'success' | 'warning' | 'info' | 'error';

const alertIcons: Record<AlertType, IconType> = {
  success: FaCheckCircle,
  warning: FaExclamationTriangle,
  info: FaInfoCircle,
  error: FaTimesCircle
};

interface AlertProps {
  type: AlertType;
  message: string;
}

function Alert({ type, message }: AlertProps) {
  const Icon = alertIcons[type];
  
  return (
    <div className={`alert alert-${type}`}>
      <Icon size={20} />
      <span>{message}</span>
    </div>
  );
}

4. Higher-Order Component

import { IconType, IconBaseProps } from 'react-icons';

function withIconWrapper(Icon: IconType) {
  return function WrappedIcon(props: IconBaseProps) {
    return (
      <div className="icon-container">
        <Icon {...props} />
      </div>
    );
  };
}

// Usage
import { FaBeer } from 'react-icons/fa';
const WrappedBeer = withIconWrapper(FaBeer);

<WrappedBeer size={24} color="orange" />

5. Dynamic Icon Loader

import { IconType } from 'react-icons';
import * as FaIcons from 'react-icons/fa';

interface DynamicIconProps {
  iconName: string;
  size?: number;
  color?: string;
}

function DynamicIcon({ iconName, ...props }: DynamicIconProps) {
  const Icon = (FaIcons as Record<string, IconType>)[iconName];
  
  if (!Icon) {
    return <span>Icon not found</span>;
  }
  
  return <Icon {...props} />;
}

// Usage
<DynamicIcon iconName="FaBeer" size={24} color="gold" />
<DynamicIcon iconName="FaCoffee" size={20} />

6. Button with Optional Icon

import { IconType, IconBaseProps } from 'react-icons';
import { ReactNode } from 'react';

interface ButtonProps {
  children: ReactNode;
  icon?: IconType;
  iconProps?: IconBaseProps;
  onClick?: () => void;
}

function Button({ children, icon: Icon, iconProps, onClick }: ButtonProps) {
  return (
    <button onClick={onClick} className="btn">
      {Icon && <Icon size={16} {...iconProps} />}
      <span>{children}</span>
    </button>
  );
}

// Usage
import { FaDownload, FaSave } from 'react-icons/fa';

<Button icon={FaDownload}>Download</Button>
<Button icon={FaSave} iconProps={{ color: 'green' }}>Save</Button>
<Button>No Icon</Button>

7. Icon Grid Component

import { IconType } from 'react-icons';

interface IconGridProps {
  icons: IconType[];
  size?: number;
  onIconClick?: (icon: IconType, index: number) => void;
}

function IconGrid({ icons, size = 32, onIconClick }: IconGridProps) {
  return (
    <div className="icon-grid">
      {icons.map((Icon, index) => (
        <div 
          key={index} 
          onClick={() => onIconClick?.(Icon, index)}
          className="icon-item"
        >
          <Icon size={size} />
        </div>
      ))}
    </div>
  );
}

8. Conditional Icon Rendering

import { IconType } from 'react-icons';
import { FaSpinner, FaCheck, FaTimes } from 'react-icons/fa';

type Status = 'loading' | 'success' | 'error' | null;

interface StatusIconProps {
  status: Status;
}

function StatusIcon({ status }: StatusIconProps) {
  let Icon: IconType | null = null;
  let color: string = 'gray';
  
  switch (status) {
    case 'loading':
      Icon = FaSpinner;
      color = 'blue';
      break;
    case 'success':
      Icon = FaCheck;
      color = 'green';
      break;
    case 'error':
      Icon = FaTimes;
      color = 'red';
      break;
  }
  
  if (!Icon) return null;
  
  return (
    <Icon 
      size={20} 
      color={color}
      className={status === 'loading' ? 'animate-spin' : ''}
    />
  );
}

Advanced Patterns

Generic Icon Component Factory

import { IconType, IconBaseProps } from 'react-icons';

function createIconComponent(
  Icon: IconType,
  defaultProps: Partial<IconBaseProps>
): IconType {
  return (props: IconBaseProps) => {
    return <Icon {...defaultProps} {...props} />;
  };
}

// Usage
import { FaBeer } from 'react-icons/fa';

const LargeBlueBeer = createIconComponent(FaBeer, {
  size: 48,
  color: 'blue'
});

<LargeBlueBeer /> // 48px blue beer icon
<LargeBlueBeer size={64} /> // Override to 64px

Icon Library Type

import { IconType } from 'react-icons';
import * as FaIcons from 'react-icons/fa';
import * as MdIcons from 'react-icons/md';
import * as AiIcons from 'react-icons/ai';

type IconLibrary = 'fa' | 'md' | 'ai';

const iconLibraries: Record<IconLibrary, Record<string, IconType>> = {
  fa: FaIcons as Record<string, IconType>,
  md: MdIcons as Record<string, IconType>,
  ai: AiIcons as Record<string, IconType>
};

function getIcon(library: IconLibrary, iconName: string): IconType | undefined {
  return iconLibraries[library][iconName];
}

// Usage
const BeerIcon = getIcon('fa', 'FaBeer');
if (BeerIcon) {
  <BeerIcon size={24} />;
}

Icon Composition

import { IconType, IconBaseProps } from 'react-icons';

interface CompositeIconProps extends IconBaseProps {
  primaryIcon: IconType;
  badgeIcon?: IconType;
}

function CompositeIcon({ 
  primaryIcon: PrimaryIcon, 
  badgeIcon: BadgeIcon,
  ...props 
}: CompositeIconProps) {
  return (
    <div className="relative inline-block">
      <PrimaryIcon {...props} />
      {BadgeIcon && (
        <div className="absolute top-0 right-0 transform translate-x-1/4 -translate-y-1/4">
          <BadgeIcon size={12} />
        </div>
      )}
    </div>
  );
}

// Usage
import { FaBell, FaCircle } from 'react-icons/fa';

<CompositeIcon 
  primaryIcon={FaBell} 
  badgeIcon={FaCircle}
  size={24}
/>

Type Guards

import { IconType } from 'react-icons';

function isIconType(value: any): value is IconType {
  return typeof value === 'function';
}

// Usage
const maybeIcon = getSomeValue();

if (isIconType(maybeIcon)) {
  <maybeIcon size={24} />;
}

Relationship to Other Types

  • IconBaseProps: The props interface that IconType functions accept
  • GenIcon: Returns an IconType function
  • IconBase: A component that can be used to create IconType components
// GenIcon returns IconType
const myIcon: IconType = GenIcon(iconData);

// IconBase is used internally by IconType components
function MyIcon(props: IconBaseProps): React.ReactNode {
  return <IconBase {...props}>{/* ... */}</IconBase>;
}

const typedIcon: IconType = MyIcon;

Source Reference

The IconType type is defined in:
  • iconBase.tsx:38 - Type definition
export type IconType = (props: IconBaseProps) => React.ReactNode;

Best Practices

  1. Use IconType for Props: When accepting an icon as a prop, always use IconType for type safety
    interface Props {
      icon: IconType; // ✓ Good
      // icon: any;   // ✗ Avoid
    }
    
  2. Capital Variable Names: When storing an icon in a variable to render, use PascalCase
    const Icon = icons[type]; // ✓ Good - PascalCase
    return <Icon size={24} />;
    
  3. Type Assertions: When dynamically importing icons, use proper type assertions
    const icons = FaIcons as Record<string, IconType>; // ✓ Good
    
  4. Optional Icons: Use optional chaining when rendering conditional icons
    {Icon && <Icon size={20} />} // ✓ Good