react-native-vector-icons icon indicating copy to clipboard operation
react-native-vector-icons copied to clipboard

[Feature]: Export type for the icon names of an icon set

Open robin-ostertag opened this issue 11 months ago • 3 comments

Is your feature request related to a problem?

First of all: The new monorepo changes are great! I'm working on a react-native app which contains a component that accepts the icon name as props and renders the icon.

There is currently no exported type for the icon name.

Describe the solution you'd like

I would like the icon name type to be exported in order for my prop to be properly typed to avoid passing invalid values for given icon set. The corresponding types for the icon name already exist.

Describe alternatives you've considered

My current solution is to use patch-package to add the export of these types.

Additional context

I was wondering if I'm missing something and this is currently possible. Otherwise, I think this would be beneficial as a feature, since I don't think this is an edge case.

Here's my code:

package.json:

"react-native": "0.76.5",
"@react-native-vector-icons/common": "^11.0.0",
"@react-native-vector-icons/fontawesome6": "^6.7.1",

Component:

import Icon, { SolidIconName } from "@react-native-vector-icons/fontawesome6";

interface Props {
    iconName?: SolidIconName;
}

const Component: FunctionComponent<Props> = ({iconName}) => (
    <Icon name={iconName} size={10}  iconStyle="solid" />
)

My changes to @react-native-vector-icons/fontawesome6/lib/typescript/module/src/index.d.ts:

+export type SolidIconName = Parameters<typeof SolidIcon>[0]['name'];

EDIT: I found this comment which proposes

import { ComponentProps } from "react";
import Icon from "@react-native-vector-icons/fontawesome6";


type Props = ComponentProps<typeof Icon>;
export type SolidIconName = Props["name"];

I believe this would work great for other fonts than fontawesome and i would prefer this over a patch file for maintainabilty reasons.

For fontawesome this does not work, as it shows types are incompatible. I believe the reason for this is, that fontawesome is providing multiple styles ("solid", "regular", etc.)

robin-ostertag avatar Jan 14 '25 15:01 robin-ostertag

@robin-ostertag Thanks for the feedback. This is a great idea and I'll look at working it into a future release

johnf avatar Jan 24 '25 23:01 johnf

sorry to ping @johnf, but is there any ETA when this feature release?

flixyudh avatar May 29 '25 08:05 flixyudh

@robin-ostertag @flixyudh Can you check out https://github.com/oblador/react-native-vector-icons/pull/1761 and let me know your thoughts?

johnf avatar Jun 07 '25 08:06 johnf

To fix these types for now you can modify lib/typescript/module/src/index.d.ts and lib/typescript/commonjs/src/index.d.ts for the respective fonts.

For Eg. I want to expose types for FontAwesome5Pro Icon names. So I have modified fontawesome5-pro/lib/typescript/module/src/index.d.ts and fontawesome5-pro/lib/typescript/commonjs/src/index.d.ts and added the following lines.

export type FontAwesome5ProRegularIconNamePropType = ComponentProps<typeof RegularIcon>['name'];
export type FontAwesome5ProBrandIconNamePropType = ComponentProps<typeof BrandIcon>['name'];
export type FontAwesome5ProDuotoneIconNamePropType = ComponentProps<typeof DuotoneIcon>['name'];
export type FontAwesome5ProLightIconNamePropType = ComponentProps<typeof LightIcon>['name'];
export type FontAwesome5ProSolidIconNamePropType = ComponentProps<typeof SolidIcon>['name'];

And you can use it as follows (I wanted to use it for Regular icon style) :

import React, { memo } from 'react';
import FontAwesomePro5, {
    FontAwesome5ProRegularIconNamePropType,
} from '@react-native-vector-icons/fontawesome5-pro';

type Props = { name: FontAwesome5ProRegularIconNamePropType };
export const CustomIcon = memo(({ name }: Props) => (
    <FontAwesomePro5
        name={name}
        size={20}
        color={'red'}
        iconStyle={'regular'}
    />
));
export default CustomIcon;

You can then patch package until this fix is available on the next releases.

Hope this helps.

abitling avatar Jun 18 '25 16:06 abitling

I'm writing a custom component as such

import React from "react";
import FontAwesome6 from "@react-native-vector-icons/fontawesome6";

import { useTheme } from "../../Hooks";

type IconProps = {
    name: React.ComponentProps<typeof FontAwesome6>["name"];
    size?: number;
    color?: string;
};

const Icon = React.memo(({ name, size, color }: IconProps) => {
    const { theme } = useTheme();

    if (!size) {
        size = theme.fontSizes.md;
    }

    if (!color) {
        color = theme.colors.text;
    }

    return <FontAwesome6 name={name} size={size} color={color} />;
});

Icon.displayName = "Icon";
export default Icon;
export type { IconProps };

I still have type(s) error(s):

Type '{ name: "0" | "sort" | "map" | "filter" | "fill" | "at" | "a" | "b" | "code" | "i" | "link" | "meta" | "p" | "q" | "s" | "section" | "table" | "u" | "video" | "circle" | "g" | "image" | ... 1872 more ... | "zhihu"; size: number; color: string; }' is not assignable to type 'IntrinsicAttributes & Props'. Type '{ name: "0" | "sort" | "map" | "filter" | "fill" | "at" | "a" | "b" | "code" | "i" | "link" | "meta" | "p" | "q" | "s" | "section" | "table" | "u" | "video" | "circle" | "g" | "image" | ... 1872 more ... | "zhihu"; size: number; color: string; }' is not assignable to type '{ name: "map" | "circle" | "image" | "font-awesome" | "address-book" | "address-card" | "bell-slash" | "bell" | "bookmark" | "building" | "calendar-check" | "calendar-days" | "calendar-minus" | ... 149 more ... | "window-restore"; size?: number | undefined; color?: ColorValue | undefined; innerRef?: Ref<...> | undef...'. Types of property 'name' are incompatible. Type '"0" | "sort" | "map" | "filter" | "fill" | "at" | "a" | "b" | "code" | "i" | "link" | "meta" | "p" | "q" | "s" | "section" | "table" | "u" | "video" | "circle" | "g" | "image" | "line" | ... 1871 more ... | "zhihu"' is not assignable to type '"map" | "circle" | "image" | "font-awesome" | "address-book" | "address-card" | "bell-slash" | "bell" | "bookmark" | "building" | "calendar-check" | "calendar-days" | "calendar-minus" | ... 149 more ... | "window-restore"'. Type '"0"' is not assignable to type '"map" | "circle" | "image" | "font-awesome" | "address-book" | "address-card" | "bell-slash" | "bell" | "bookmark" | "building" | "calendar-check" | "calendar-days" | "calendar-minus" | ... 149 more ... | "window-restore"'.ts(2322)

pistou avatar Jul 01 '25 20:07 pistou

#1761 has now been merged and will be released shortly

johnf avatar Jul 12 '25 13:07 johnf

it seems these new types aren't usable? see also #1814

Rexogamer avatar Jul 21 '25 22:07 Rexogamer