React-fontawesome: Font-awesome issue with Reactjs & Typescript

Created on 19 Jun 2018  路  9Comments  路  Source: FortAwesome/react-fontawesome

I am working on React Redux and typescript app.
My package.json contains following versions of font awesome.

    "@fortawesome/fontawesome": "^1.1.8",
    "@fortawesome/fontawesome-common-types": "^0.1.7",
    "@fortawesome/fontawesome-free-brands": "^5.0.13",
    "@fortawesome/fontawesome-free-regular": "^5.0.13",
    "@fortawesome/fontawesome-free-solid": "^5.0.13",
    "@fortawesome/react-fontawesome": "0.0.20",

My App.tsx looks like this in which i am using External Loading loading method to configure fontawesome in project.

import * as React from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import Counter from './containers/Counter';

// Font awesome Stuff for Global Use
import fontawesome from '@fortawesome/fontawesome';
import brands from '@fortawesome/fontawesome-free-brands';
import regular from '@fortawesome/fontawesome-free-regular';
import solid from '@fortawesome/fontawesome-free-solid';
fontawesome.library.add(brands, regular, solid);

class App extends React.Component {
  public render() {
    return (
      <BrowserRouter>
        <div>
          <p>Hello</p>
          <Route path="/" component={Counter} />
        </div>
      </BrowserRouter>
    );
  }
}
export default App;

My Counter.tsx which is in Components folder looks like this.

import * as React from 'react';
import { connect } from 'react-redux';
import FontAwesomeIcon from '@fortawesome/react-fontawesome';

export interface IAppProps {
  counter: number;
  onIncrementCounter: any;
}

class Counter extends React.Component {
  public props: IAppProps;
  public render() {
    return (
      <div>
        <p onClick={this.props.onIncrementCounter}>Counter: {this.props.counter}</p>
        <FontAwesomeIcon icon="check-square" />
        Popular gadgets come from vendors like:
        <FontAwesomeIcon icon={['fab', 'apple']} />
        <FontAwesomeIcon icon={['fab', 'microsoft']} />
        <FontAwesomeIcon icon={['fab', 'google']} />
      </div>
    );
  }
}

const mapStateToProps = (state: any)=>{
  return {
    counter: state.counter
  }
}

const mapDispatchToProps = (dispatch: any)=>{
  return {
    onIncrementCounter: ()=> { 
      dispatch({type: 'INCREMENT'})
    },
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Counter);

But it is giving me this issue

`Failed to compile.

/Users/cdalvi/Documents/typescript/mace-vaa-frontend/src/containers/Counter.tsx
(3,29): Could not find a declaration file for module '@fortawesome/react-fontawesome'. 
'/Users/cdalvi/Documents/typescript/mace-vaa-frontend/node_modules/@fortawesome/react-fontawesome/index.js' implicitly has an 'any' type.
  Try `npm install @types/fortawesome__react-fontawesome` if it exists or add a new declaration 
(.d.ts) file containing `declare module 'fortawesome__react-fontawesome';`

I checked this #125 but
Hard Luck :(

Most helpful comment

Hello,

I'd like to share my solution to this issue.
You need to set your icon as type IconName, [IconPrefix, IconName] or IconLookup. See here.
Make sure to cast your string icons (For example: const icon = 'coffee' as IconName).

import { FunctionComponent } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { IconName } from '@fortawesome/fontawesome-common-types';

type Props = {
  title: string,
  icon: IconName,
};

const ComponentExample: FunctionComponent<Props> = ({ title, icon }: Props) => {
  return (
    <div>
      <h3>{title}</h3>
      <FontAwesomeIcon icon={icon} />
    </div>
  );
};

export default ComponentExample;

All 9 comments

@chinmaydalvi we've just released a new version of this component. Can you check out https://github.com/FortAwesome/react-fontawesome/blob/master/UPGRADING.md and see if it doesn't resolve your issues?

I completely uninstall old font and added latest font version
My package.json contains following versions of font awesome.

    "@fortawesome/fontawesome-svg-core": "^1.2.0-14",

    "@fortawesome/free-brands-svg-icons": "^5.1.0-11",

    "@fortawesome/free-solid-svg-icons": "^5.1.0-11",

    "@fortawesome/react-fontawesome": "0.1.0-11",

I added font awesome in my App.tsx file

import { library } from '@fortawesome/fontawesome-svg-core';

import { fab } from '@fortawesome/free-brands-svg-icons';

import { faCheckSquare, faCoffee } from '@fortawesome/free-solid-svg-icons';

library.add(fab, faCheckSquare, faCoffee);

and when I tried to use font awesome in Layers.tsx one component in following way

import * as React from 'react';
import * as scss from './Layers.scss';
import {LAYERS_DATA} from '../../../data/layers-dataset';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';


interface ILayerStateProps{
  hello?: string,
  faCheckSquare?: string
}

interface ILayerState{
  layers: any;
  visibleLayers: any
}

class Layer extends React.Component<ILayerStateProps, ILayerState>{
  public layers: any = '';
  constructor(props: any){
    super(props);
    this.toggleDataSets = this.toggleDataSets.bind(this);

    this.state = {
      layers: LAYERS_DATA,
      visibleLayers: [],
    }
  }

  public toggleDataSets(event:any){
    console.log(event.target.dataset.layer)
    const visibleLayers:any = [...this.state.visibleLayers];
    const layerIndex: number = visibleLayers.indexOf(event.target.dataset.layer);
    if(layerIndex === -1){
      visibleLayers.push(event.target.dataset.layer);
    }else{
      visibleLayers.splice(layerIndex, 1);
    }
    console.log(visibleLayers);
    this.setState({
      visibleLayers
    })
  }

  public renderLayers(){
    return this.state.layers.map((layer:any, index: number)=>{
      return(
        <li key={index}>
          <div className={scss.layername}>
            <p onClick={this.toggleDataSets} 
               data-layer={layer.name}><FontAwesomeIcon icon="faCoffee" />{layer.name}</p>
          </div>
          <div className={this.state.visibleLayers.indexOf(layer.name) === -1 ? `${scss.hideDatasets}`: `${scss.dataset}`}>
            {layer.datasets.map((dataset:any, datasetIndex: number)=>{
              return <p key={`${dataset}-${datasetIndex}`}>{dataset}</p>;
            })}
          </div>
        </li>
      );
    });
  }

  public render(){
    return(
      <>
        <div className={scss.layer}>
          <ul>
            {this.renderLayers()}
          </ul>
        </div>
      </>
    );
  }
}

export default Layer;

It gives me this error

[ts]
Type '{ icon: "faCoffee"; }' is not assignable to type 'IntrinsicAttributes & Props'.
  Type '{ icon: "faCoffee"; }' is not assignable to type 'Props'.
    Types of property 'icon' are incompatible.
      Type '"faCoffee"' is not assignable to type 'IconProp'.

@chinmaydalvi can you provide a reproduction test case? https://stackblitz.com is a good choice as it supports TS.

I ran into a similar issue and got things working:

    "@fortawesome/fontawesome-free": "^5.2.0",
    "@fortawesome/fontawesome-svg-core": "^1.2.0-14",
    "@fortawesome/free-solid-svg-icons": "^5.1.0-11",
    "@fortawesome/react-fontawesome": "0.1.0-11",

The key for me was to change my import statement from:

import FontAwesomeIcon from '@fortawesome/react-fontawesome';

to:

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

Also it looks like you might not be using the correct icon name.

<FontAwesomeIcon icon="faCoffee" />

should be:

<FontAwesomeIcon icon="coffee" />

This is an easy to miss nugget on the main readme page:

faCheckSquare and faCoffee: Adding each of these icons individually allows us to refer to them throughout our app by their icon string names, "check-square" and "coffee", respectively.

Faced the same problem.

import * as React from 'react';

import { library } from '@fortawesome/fontawesome-svg-core';
import { faPlayCircle } from '@fortawesome/free-regular-svg-icons';
import { faAddressBook } from '@fortawesome/free-solid-svg-icons';

import 'bootstrap/dist/css/bootstrap.css';
import './storybook.css';

library.add(faPlayCircle, faAddressBook);

const EngineWrapper: React.SFC = (props) => (
  <div className="wrapper">
    { props.children }
  </div>
);

export default EngineWrapper;

Such component doesn't compile.
ERROR in ./src/stories/Wrapper.tsx (10,13): error TS2345: Argument of type 'IconDefinition' is not assignable to parameter of type 'IconDefinitionOrPack'. Type 'IconDefinition' is not assignable to type 'IconPack'. Index signature is missing in type 'IconDefinition'.

Why @fortawesome/free-regular-svg-icons and '@fortawesome/free-solid-svg-icons' have different interfaces? And what should to do if I need regular icons, especially this one?

@EvgeniyRRU please provide a reproducible test case and we'll take a look.

@chinmaydalvi by chance does <FontAwesomeIcon icon="coffee" /> work?

It worked when I use
<FontAwesomeIcon icon={["fas", 'filter']}/>

I am using following versions in my project

`

 "@fortawesome/fontawesome-svg-core": "^1.2.0-14",

"@fortawesome/free-brands-svg-icons": "^5.1.0-11",

"@fortawesome/free-regular-svg-icons": "^5.1.0-11",

"@fortawesome/free-solid-svg-icons": "^5.1.0-11",

"@fortawesome/react-fontawesome": "0.1.0-11",

`

Hello,

I'd like to share my solution to this issue.
You need to set your icon as type IconName, [IconPrefix, IconName] or IconLookup. See here.
Make sure to cast your string icons (For example: const icon = 'coffee' as IconName).

import { FunctionComponent } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { IconName } from '@fortawesome/fontawesome-common-types';

type Props = {
  title: string,
  icon: IconName,
};

const ComponentExample: FunctionComponent<Props> = ({ title, icon }: Props) => {
  return (
    <div>
      <h3>{title}</h3>
      <FontAwesomeIcon icon={icon} />
    </div>
  );
};

export default ComponentExample;
Was this page helpful?
0 / 5 - 0 ratings