TypeScript Icons: Strict Typing & Polymorphic Wrappers (2026)
Eliminate runtime SVG rendering bugs with strict TypeScript interfaces. Discover how typed icon properties, generic polymorphic components, and IDE autocompletion improve developer productivity.
1. Building a Production Type-Safe Icon Wrapper
When architecting a frontend design system, wrap your icon components in a typed polymorphic wrapper. This centralizes default sizing, accessibility attributes (aria-hidden), and theme classes:
// components/ui/icon.tsx
import React from 'react'
import { LucideIcon, LucideProps } from 'lucide-react'
export interface IconProps extends Omit<LucideProps, 'ref'> {
icon: LucideIcon
label?: string // Optional accessible label
className?: string
}
export function AppIcon({ icon: IconComponent, label, className = '', size = 20, ...rest }: IconProps) {
return (
<IconComponent
size={size}
className={className}
aria-hidden={!label}
aria-label={label}
role={label ? 'img' : 'presentation'}
{...rest}
/>
)
}
// Usage in your React / Next.js app:
// <AppIcon icon={Home} size={24} className="text-blue-500" label="Go to homepage" />Core Advantages of Native TypeScript Support
VS Code and JetBrains IDEs instantly suggest symbol names as you type, reducing typos and API lookups.
Catch invalid size strings, missing colors, or unsupported SVG stroke values at build-time.
Rename and migrate icon primitives across hundreds of files safely with automated TypeScript refactoring.
Hover over any icon component in your IDE to see its bounding box, stroke defaults, and tags.
Verified TypeScript Icon Libraries (11)
LIBRARIES REQUIRING MANUAL TYPE DEFINITIONS (7)
TypeScript & SVG Icons FAQ
What is the standard TypeScript type for React SVG icon components?
Most modern libraries export a dedicated prop interface (e.g., `LucideProps` from lucide-react) or extend standard SVG component props: `React.ComponentPropsWithoutRef<"svg"> & { size?: number | string; strokeWidth?: number | string }`. This ensures full compatibility with standard HTML SVG attributes.
How does verbatimModuleSyntax affect SVG icon imports in TypeScript 5+?
With `verbatimModuleSyntax: true` enabled in tsconfig.json, TypeScript strictly distinguishes type imports from runtime value imports. Value imports like `import { Home } from "lucide-react"` will be preserved as runtime JS, while type imports like `import type { LucideIcon } from "lucide-react"` are completely stripped at compile time.
How do I build a generic dynamic Icon component in TypeScript without bundling all icons?
Define an explicit string union type (e.g., `type IconName = "home" | "settings" | "user"`) and map each key to a statically imported component in an internal map object. TypeScript will provide strict compile-time autocomplete and prevent invalid string keys.
Why do some legacy icon packages have missing or broken .d.ts declaration files?
Older libraries published before the ESM migration frequently shipped CommonJS-only code or generated declarations with ambient namespaces that fail under strict modern `moduleResolution: "bundler"` or `"node16"`. All libraries highlighted on this page ship native .d.ts or .d.mts declarations.
Explore Next.js & React Guides
Learn how to render typed icons in Next.js Server Components and React.