0

I think I am using the correct syntax/terms, if not please let me know. I am transitioning a project to typescript and it's going ok -- The index.tsx file currently sets React.icons to an object of custom icons from the coreui library. Using typescript, Property 'icons' does not exist on type 'typeof React'.

I think I need to extend the React interface/type declaration to include icons as a typeof React.

The error is present under the first icons in React.icons = icons from the code below. If anyone can point me in the right direction, i'd be happy.

import "react-app-polyfill/ie11"; // For IE 11 support
import "react-app-polyfill/stable";
import "core-js";
import "./polyfill";
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import App from "./App";
import * as serviceWorker from "./serviceWorker";

import store from "./store";

import { icons } from "./assets/icons";

interface IReactIcons extends React {
  icons: object;
}

React.icons = icons;

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

serviceWorker.unregister();

Trying to add Module Augmentation below:

import "react-app-polyfill/ie11"; // For IE 11 support
import "react-app-polyfill/stable";
import "core-js";
import "./polyfill";
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import App from "./App";
import * as serviceWorker from "./serviceWorker";

import store from "./store";

import { icons } from "./assets/icons";

declare module "react" {
  interface React {
    icons: {};
  }
}

React.icons = icons;

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

serviceWorker.unregister()
Nick McLean
  • 601
  • 1
  • 9
  • 23
  • 2
    Is there a reason that you do not want to just use `icons` from `import { icons } from "./assets/icons";` to render the icons when needed? Why extend react and add an icons field? – Jack Campbell Apr 02 '21 at 21:28
  • Not going to lie - I have it this way based off what I saw the makers of the icons do. If I remove the `React.icons = icons` then none of the icons render. – Nick McLean Apr 02 '21 at 21:30
  • 2
    So it looks like `React.icons` is used as a global var to access the icons. I would suggest refactoring the code to import the icons when needed and render them directly on the components instead of extending `React`. – Jack Campbell Apr 02 '21 at 21:34
  • I think you are right, the library provides a component to use called -- This component must use that global var to access the icons. – Nick McLean Apr 02 '21 at 21:35
  • You need to "augment the module", see e.g. https://stackoverflow.com/q/46493253/3001761 – jonrsharpe Apr 02 '21 at 21:38
  • Thanks Jon! I'll check this out. – Nick McLean Apr 02 '21 at 21:40
  • Hey @jonrsharpe -- I followed a guide and am looking at the documentation - I think I did it right, but TS is still mad about the same problem. I posted it to the bottom of the question above to show, if you have time. If not, then thanks for the help so far!! – Nick McLean Apr 02 '21 at 21:53
  • Actually I lied, accidentally - It updated the error - `Property 'icons' does not exist on type 'typeof import("/home/nickisyourfan/Desktop/DEV/OnDeBand/app/node_modules/@types/react/index.d.ts")'.` – Nick McLean Apr 02 '21 at 21:57

1 Answers1

1

You can't use modal augmentation because as it is stated it the docs:

  1. You can’t declare new top-level declarations in the augmentation — just patches to existing declarations.
  2. Default exports also cannot be augmented, only named exports

Good new is that you can use global augmentation instead

declare global {
  namespace React {
    let icons:any;
  }
}

If you know what types your icons are use it instead of any

Nadia Chibrikova
  • 4,916
  • 1
  • 15
  • 17