TS Bug - @rneui/base@5.0.0 — Undeclared type dependency causes IconProps to lose color/name/size · Issue #4027 · react-native-elements/react-native-elements · GitHub
Skip to content

TS Bug - @rneui/base@5.0.0 — Undeclared type dependency causes IconProps to lose color/name/size #4027

@pweisensee

Description

@pweisensee

Is there an existing issue for this?

  • I have searched the existing issues

Explain what you did

use Icon with color props

Expected behavior

TS compiles and validates props correctly.

Describe the bug

Summary

@rneui/base publishes a .d.ts file that imports types from react-native-vector-icons, but that package is not listed in dependencies or peerDependencies. It is only in devDependencies, which are never installed by consumers. As a result, TypeScript cannot resolve IconButtonProps from react-native-vector-icons/Icon, and the props it contributes to IconProps — including color, name, and size — silently disappear from the public API surface. Every use of <Icon color="..." name="..." size={...} /> produces a TS2322 type error.


The Problematic Line

File: node_modules/@rneui/base/dist/Icon/Icon.d.ts (line 3)

import { type IconButtonProps, type IconProps as VectorIconProps } from 'react-native-vector-icons/Icon';

export interface IconProps extends InlinePressableProps, IconButtonProps {
  // ...
}

IconButtonProps (from react-native-vector-icons) contributes color, name, and size to IconProps. When TypeScript cannot resolve react-native-vector-icons/Icon, the extends IconButtonProps clause silently contributes nothing and those props vanish.


Errors Produced

TS2322: Type '{ color: string; name: string; }' is not assignable to type
'IntrinsicAttributes & IconProps & { children?: ReactNode; } & RefAttributes<...>'.
  Property 'color' does not exist on type 'IntrinsicAttributes & IconProps & ...'

TS2353: Object literal may only specify known properties, and 'color' does not exist
in type 'Partial<IconProps> | ((props: Partial<IconProps>, theme: ...) => Partial<IconProps>)'.

These errors appear on every file that uses <Icon color=... name=... size=... />, and also in any theme configuration that sets a default Icon color.


Why This Happens

In a published TypeScript library, any package referenced in a distributed .d.ts file must appear in one of:

Location Meaning
dependencies Installed automatically alongside your package
peerDependencies Consumer is expected to install it; package manager warns if missing
Inlined Types declared directly in the .d.ts — no external import

react-native-vector-icons appears in none of these in @rneui/base@5.0.0. It is only in devDependencies, which npm/yarn/pnpm never install for consumers.

The smoking gun

@rneui/base/package.json (v5.0.0):

{
  "devDependencies": {
    "@types/react-native-vector-icons": "^6.4.10"
  },
  "peerDependencies": {
    "react-native-safe-area-context": ">= 3.0.0"
  }
}

The library lists @types/react-native-vector-icons in its own devDependencies — precisely what resolves the import during development. That requirement was never propagated to consumers.


Affected Projects

Any project that:

  • Uses @rneui/base or @rneui/themed v5.0.0
  • Does not already have react-native-vector-icons or @types/react-native-vector-icons installed for another reason

Expo-based projects are especially affected because they use @expo/vector-icons instead of react-native-vector-icons, so the old package is never present.

Suggested Fixes

Option 1 — Best: Inline the required types (no external import)

Remove the import from react-native-vector-icons/Icon in the .d.ts and declare the interfaces directly. They are small and stable:

// Icon.d.ts
interface VectorIconBaseProps<GLYPHS extends string = string> {
  name: GLYPHS;
  size?: number;
  color?: string | import('react-native').OpaqueColorValue;
  iconStyle?: import('react-native').StyleProp<import('react-native').TextStyle>;
}

interface IconButtonProps<GLYPHS extends string = string>
  extends VectorIconBaseProps<GLYPHS>,
    import('react-native').ViewProps,
    import('react-native').TouchableHighlightProps {}

export interface IconProps extends InlinePressableProps, IconButtonProps { ... }

This removes the external type dependency entirely. No consumer ever needs to install anything extra. This is the standard pattern for libraries that wrap third-party components but want to own their public type surface.


Option 2 — Acceptable: Add to peerDependencies as optional

{
  "peerDependencies": {
    "react-native-vector-icons": ">=9.0.0",
    "react-native-safe-area-context": ">= 3.0.0"
  },
  "peerDependenciesMeta": {
    "react-native-vector-icons": { "optional": true }
  }
}

This causes package managers to warn consumers when the dep is missing and documents the requirement. Downside: forces Expo projects to install a native module they don't use at runtime, even as a type-only dep.


Option 3 — Acceptable: Add @types/react-native-vector-icons to peerDependencies

{
  "peerDependencies": {
    "@types/react-native-vector-icons": ">=6.4.0",
    "react-native-safe-area-context": ">= 3.0.0"
  },
  "peerDependenciesMeta": {
    "@types/react-native-vector-icons": { "optional": true }
  }
}

Lighter than Option 2 (types only, no native module) and mirrors what the library already does internally. Still requires consumers to install an extra package.


Option 4 — Future: Align published types with the new scoped packages

@rneui/base v5 devDependencies already use @react-native-vector-icons/material-icons, @react-native-vector-icons/ionicons, etc. (the v12 rewrite). The published .d.ts still references the old react-native-vector-icons namespace. Aligning the published types with the new scoped packages would be more consistent, though it still requires a peer dep declaration.


Consumer Workaround (until fixed)

Add to the consuming project's devDependencies:

yarn add -D @types/react-native-vector-icons

This resolves the type import and restores color/name/size on IconProps with no code changes required.

Steps To Reproduce

## Minimal Reproduction

**1. Create a new Expo project:**


npx create-expo-app repro && cd repro


**2. Install `@rneui` packages — no `react-native-vector-icons`:**


yarn add @rneui/themed @rneui/base


**3. Create `src/App.tsx`:**


import { Icon } from '@rneui/themed';

export default function App() {
  // TS2322: Property 'color' does not exist on type '...'
  return <Icon name="close" color="red" size={24} />;
}


**4. Run the type checker:**


npx tsc --noEmit


- **Expected:** no errors — these are valid, documented `Icon` props
- **Actual:** TS2322 — `color`, `name`, and/or `size` reported as unknown properties

**5. Confirm the root cause with the workaround:**


yarn add -D @types/react-native-vector-icons
npx tsc --noEmit  # errors are gone

Screenshots

No response

Your Environment

`npx @rneui/envinfo`
  ```

Global Dependencies:

No related dependency found

Local Dependencies:

  • @rneui/base : ^5.0.0

  • @rneui/themed : ^5.0.0

  • expo : ^54.0.33

  • react : 19.1.0

  • react-native : 0.81.5

  • @types/react : ~19.1.17

    
    

Metadata

Metadata

Assignees

Labels

component: IconIssue related to Icon Component

Type

Projects

Status

No status

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions