Reputation: 14328
I'm using @fortawesome
and @fortawesome/react-fontawesome
. @fortawesome/fontawesome-common-types
defines IconDefinition
as
export interface IconLookup {
prefix: IconPrefix;
// IconName is defined in the code that will be generated at build time and bundled with this file.
iconName: IconName;
}
export interface IconDefinition extends IconLookup {
icon: any[];
}
export type IconProp = IconLookup | /*...*/;
export type IconName = /* a lot of concatenated strings */;
@fortawesome/react-fontawesome
defines
export function FontAwesomeIcon(props: Props): JSX.Element;
export interface Props {
icon: IconProp;
/* ... */
}
I wanted to add my own SVGs and use them in the icon
property of <FontAwesomeIcon />
.
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
type CustomIconName = 'myCustomIcon' /* | ... */;
interface CustomIconDefinition extends Pick<IconDefinition, Exclude<keyof IconDefinition, 'iconName'>> {
prefix: 'fab',
iconName: CustomIconName;
}
const MyCustomIcon: CustomIconDefinition = /* ... */;
export default function() {
let icon: any = MyCustomIcon;
return <FontAwesomeIcon icon={icon} />;
}
This works so long as icon
is of type any
.
I'd like to remove CustomIconDefinition
and overwrite or extend the IconName
definition to include MyCustomIcon
.
I thought to do something like:
import { IconName as VanillaIconName } from '@fortawesome/fontawesome-common-types';
declare module "@fortawesome/fontawesome-common-types" {
export type IconName = VanillaIconName | MyCustomIcon;
}
This results in Duplicate identifier 'IconName'. index.d.ts(16,13): 'IconName' was also declared here.
I suspect even if I get around this, it's going to have an error because IconName = VanillaIconName
introduces a circular definition.
I also thought to overwrite the FontAwesomeIcon
definition, but I didn't get far on that one because icon: IconProp
is several types deep. I suppose I could create my own CustomFontAwesomeIcon extends FontAwesomeIcon
, but this isn't ideal.
Upvotes: 7
Views: 4714
Reputation: 14328
It occurred to me 2.5 years later that while type
augmentation declaration merging isn't possible, interface
declaration merging is.
I haven't tested this code yet, as I don't even remember which project I needed this for, but I should™ be able to augment Props
of @fortawesome/react-fontawesome
.
import { IconProp } from '@fortawesome/fontawesome-common-types';
declare module '@fortaweome/react-fontawesome' {
export interface Props {
icon: CustomIconProp;
}
}
type CustomIconName = 'myCustomIcon' /* | ... */;
interface CustomIconProp extends Omit<IconProp, 'iconName'> {
iconName: CustomIconName;
}
This doesn't solve the question posed in the title, but does solve the problem I had.
Note: there is an uber-hacky way to solve the problem posed by the title, by overwriting the package's declaration file using patch-package
. Regrettably, I've taken this approach before for a dependency version I was bound to, but which future versions fixed the type I needed.
Upvotes: 3