Struggling with defining types in NextJs when using dynamic imports in Typescript and NextJs

I have successfully created a component that utilizes next/dynamic to import react-icons only when needed. However, I am struggling to properly define the TypeScript types for this component. Despite this issue, the component itself is functioning as expected.

For those interested in viewing the TypeScript code, here is a link to the codesandbox: https://codesandbox.io/s/nextjs-dynamic-import-with-react-icons-zk1kz9

The code :

import dynamic from "next/dynamic";

const DynamicIcon = ({
  iconFamily,
  icon,
  ...rest
}: {
  iconFamily: keyof typeof Icons;
  icon: string;
}) => {
  const Icons = {
    // Dynamic imports for various icon families
  };

  const Icon = iconFamily && icon ? Icons[iconFamily] : null;

  if (!Icon) return <></>;

  return (
    <>
      <Icon {...rest} />
    </>
  );
};

export default DynamicIcon;

The error :

./components/DynamicIcon.tsx:12:17
Type error: Argument of type '() => Promise<typeof import("/sandbox/node_modules/react-icons/ci/index") | IconType | undefined>' is not assignable to parameter of type 'DynamicOptions<IconBaseProps> | Loader<IconBaseProps>'.
  Type '() => Promise<typeof import("/sandbox/node_modules/react-icons/ci/index") | IconType | undefined>' is not assignable to type '() => LoaderComponent<IconBaseProps>'.
    Type 'Promise<typeof import("/sandbox/node_modules/react-icons/ci/index") | IconType | undefined>' is not assignable to type 'LoaderComponent<IconBaseProps>'.
      Type 'typeof import("/sandbox/node_modules/react-icons/ci/index") |IconType | undefined' is not assignable to type 'ComponentType<IconBaseProps> | { default: ComponentType<IconBaseProps>; }'.
        Type 'undefined' is not assignable to type 'ComponentType<IconBaseProps> | { default: ComponentType<IconBaseProps>; }'.

I have attempted multiple methods of defining the type (such as strings or keyof typeof IconType), but have not yet found a solution.

Answer №1

"react-icons/*" is fetching components of type ReactComponent.

import { ComponentType } from "react";

type IconsType = { [key in typeof iconFamily]: ComponentType<any> };

const Icons: IconsType = {
    ci: dynamic(() => import("react-icons/ci").then((mod) => mod[icon])),
    ...
}

Answer №2

It seems like the problem lies in your use of returning a Promise in this section.

ci: dynamic(async () => {
    const mod = await import("react-icons/ci");
    return mod[icon];
})

Furthermore, you are passing the variable icon as a string, when it should actually be a value exported by the react-library. Consider defining an Enum type for the possible values of icon.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can you explain the process for accessing a parent function in Angular?

I have a form component that inserts data into a database upon submission, and I need to update the displayed data in another component once it changes in the database. I attempted using ViewChild to invoke the necessary functions, but encountered issues w ...

Generating a collection of objects using arrays of deeply nested objects

I am currently working on generating an array of objects from another array of objects that have nested arrays. The goal is to substitute the nested arrays with the key name followed by a dot. For instance: const data = [ id: 5, name: "Something" ...

Creating a WebExtension using Angular and TypeScript

I am currently working on creating a WebExtension using Angular and Ionic. The extension successfully loads the application and enables communication between Content Script and Background Script. However, I am facing an issue where the TypeScript code is n ...

Error Encountered with Google Authentication in Localhost:3001 - Warning of 'Blocked Access'

Encountering a Next-auth Google authentication issue on my localhost development setup. Admin side (localhost:3000) and client side (localhost:3001) of e-commerce website are separate instances. Error message "access blocked" when trying Google authentica ...

The issue arose as a result of a SQLITE_ERROR, specifically mentioning that the Users table does not exist. However, the model has been

Greetings! I am currently facing an issue while trying to integrate the "sequelize-typescript" library into my Express.JS REST API that I developed using Dependency Injection. The error I am encountering is: SQLite Error: no such table: Users Below is th ...

What issues are causing problems with the dynamic routing in Nextjs?

I apologize if this question has been asked before, or if I am approaching it incorrectly. Currently, I am in the process of developing a Next.js application with plans to integrate Shopify/Hydrogen in the future. Right now, I am working on creating a dyna ...

"What steps should be taken to set up the router in Nextjs prior to rendering any components

Currently, I am working with react-query and facing an issue. When I try to retrieve the id from the URL and use it in getSubject function, it ends up passing an undefined value like this: http://localhost:3000/api/subject/undefined Interestingly, if I cl ...

Exploring methods for retrieving local storage data in Next.js

Having recently transitioned from React to Next.js, I am facing an issue with saving a token in local storage for authentication. Since Next.js is server-based, I am encountering errors when trying to access the token later. I would appreciate any suggesti ...

Conditionally setting a property as optional in Typescript

Imagine a scenario where I have a type defined as interface Definition { [key: string]: { optional: boolean; } } Can we create a type ValueType<T extends Definition> that, given a certain definition like { foo: { optional: true } ...

Upcoming Step 13: Load user preferences and data from localStorage

In my React component within Next.js, I have implemented a tabular structure that saves and restores user's column preferences using localStorage. It is important for the component to load these preferences before displaying any part of the table. Di ...

Successfully upgraded Angular 7 to 8, however, encountering an issue with the core not being able to locate the rxjs module

After updating my Angular version from 7.X to 8.2.5, everything seemed fine until I started getting errors related to the rxjs module within the angular/core package. Despite having the latest version of rxjs (6.5.3), the errors persisted even after removi ...

What is preventing type guarding in this particular instance for TypeScript?

Here is an example of some code I'm working on: type DataType = { name: string, age: number, } | { xy: [number, number] } function processInput(input: DataType) { if (input.name && input.age) { // Do something } e ...

Creating test cases for a service that relies on a Repository<Entity> to consume another service

Having trouble creating tests for an auth.service that seems pretty straightforward from the title. However, every time I run the tests, I encounter this error: TypeError: Converting circular structure to JSON --> starting at object with cons ...

NextJS Multilingual ToolBox

I'm working on a NextJS application and I've been trying to integrate the Google auto-translate widget into my app. After creating the following function: function googleTranslateElementInit() { if (!window['google']) { con ...

Determine whether an element is visible following a state update using React Testing Library in a Next.js application

I'm looking to test a NextJS component of mine, specifically a searchbar that includes a div which should only display if the "search" state is not empty. const SearchBar = () => { const [search, setSearch] = useState(""); const handleSear ...

What is the best method for translating object key names into clearer and easier to understand labels?

My backend server is sending back data in this format: { firstName: "Joe", lastName: "Smith", phoneNum: "212-222-2222" } I'm looking to display this information in the frontend (using Angular 2+) with *ngFor, but I want to customize the key ...

Implementing dynamic display of div based on dropdown selection in typescript

A solution is needed to display or hide specific div elements based on a dropdown selection using Typescript. Sample HTML file: <select class="browser-default custom-select"> <option selected>single</option> <option value="1"> ...

Organizing an array based on designated keywords or strings

Currently, I am in the process of organizing my logframe and need to arrange my array as follows: Impact Outcomes Output Activities Here is the initial configuration of my array: { id: 15, parentId: 18, type: OUTPUT, sequence: 1 }, { id: 16, parentId: ...

Issues encountered when using AngularJS2's post method to send data to an ASP.NET Core backend result

I recently delved into learning Angular2 and Asp.net core, but I encountered an issue when trying to post an object. Here is the relevant code snippet: Service.ts file: export class SubCategoryService { //private headers: Headers; constructor(private htt ...

Exploring the File Selection Dialog in Node.js with TypeScript

Is it possible to display a file dialog in a Node.js TypeScript project without involving a browser or HTML? In my setup, I run the project through CMD and would like to show a box similar to this image: https://i.stack.imgur.com/nJt3h.png Any suggestio ...