[Feature]: Export type for the icon names of an icon set
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 Thanks for the feedback. This is a great idea and I'll look at working it into a future release
sorry to ping @johnf, but is there any ETA when this feature release?
@robin-ostertag @flixyudh Can you check out https://github.com/oblador/react-native-vector-icons/pull/1761 and let me know your thoughts?
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.
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)
#1761 has now been merged and will be released shortly
it seems these new types aren't usable? see also #1814