Identifying the category of dynamic module in TypeScript version 2.4

Exploring the exciting new dynamic module support in TS 2.4 has been a great experience, but I encountered a minor issue along the way:

While using import().then(...), the type of the module is specified. However, I faced a situation where I needed to store the promise for future use without losing the module type information.

I attempted to implement dynamic loading in a wrapper react component (although react-router v4 would have been more suitable) by initiating the load at constructor and triggering a reload when the component is first mounted. Although there was a slight "flickering" issue, the functionality was still effective:

import * as React from 'react'

export class DashboardDynamic extends React.Component<any, any> {
    constructor(props) {
        super(props)

        // At this point, typescript can determine the type of the import, including the "Dashboard" export
        this.loaderPromise = import(/* webpackChunkName: "dashboard" */ './Dashboard')
    }

    componentDidMount() {
        // Promise<any> assigns the {Dashboard} component an "any" type
        this.loaderPromise.then(({Dashboard}) => {
            this.myContent = <Dashboard {...this.props}/>
            this.forceUpdate()
        })
    }

    myContent: JSX.Element = <div />;
    loaderPromise: Promise<any> = null // ISSUE: "any", not module type.

    render() {
        return this.myContent
    }
}

If anyone knows how to correctly define the promise type to preserve the dynamic module's type, I'd greatly appreciate your insights.

Answer №1

Currently, it seems that using typeof import('./Dashboard') is not a feasible option. However, one workaround could involve creating a higher-order component to abstract the logic in componentDidMount while maintaining type integrity from the import.

The typed implementation would look like this:

function dynamicComponent<Props>(loader: () => Promise<React.ComponentType<Props>>): React.ComponentType<Props>

Usage example:

const DynamicDashboard = dynamicComponent(() => import('./Dashboard').then(({ Dashboard }) => Dashboard)))

Answer №2

I have found a solution, although not the most elegant one:

By breaking down the load process into a function, we can utilize the clever method for extracting return type from a function to determine the type. This results in:

const loadDashboard = () => import(/* webpackChunkName: "dashboard" */ './Dashboard')
const loadTypeDummy = (false as true) && loadDashboard()
type IDashboardModule = typeof loadTypeDummy

The variable IDashboardModule now represents a promise type that can define the member variable.

UPDATE: In TypeScript 2.8, you can simply use

ReturnType<typeof loadDashboard>
to bypass the need for invoking a dummy function. Take a look at the magic behind the definition of ReturnType.

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

Guide on specifying the return type for Rx.Observable.fromPromise() in TypeScript

My current problem involves a function that returns an Rx.Observable created from a promise. Here is the code snippet: var data$ = fetchData(); fetchData() { return Rx.Observable.fromPromise(fetch("someUrl")); } When I hover over the variable data$ i ...

Error: Unable to access the 'secondary' property of an undefined object - encountered after updating Material-UI from version 4 to version 5

We recently completed an upgrade from MUI version 4 to version 5, and since the upgrade, our UI tests have been failing with the following error: TypeError: Cannot read property 'secondary' of undefined (I added comment to which line in code thi ...

What is the meaning of boolean true in a Firestore query using TypeScript?

Currently, I am facing an issue with querying Firestore in Angular 8 using AngularFire. While querying a string like module_version works perfectly fine as shown in the code snippet below, the problem arises when attempting to query a boolean field in Fire ...

In the vue3 v-for loop, the type of 'Item' is considered to be 'unknown'

https://i.sstatic.net/irjFP.png Currently, I am facing an issue with a v-for loop in my Vue3 + TypeScript project. The error message keeps appearing despite following the correct syntax for passing props to a component. I have included the relevant code s ...

Assessing the invalidity of user-defined type guards within class implementations

I just wrote this Typescript code and tested it in a sandbox. Check out the code snippet below: class Foo { public get test() : string|number{ return "foo" } public hasString() : this is { test:string }{ return type ...

Configuring the React Typescript router to support username-based URLs should be done in a way that does not cause conflicts with other routes

I am looking to display a user's profile on a URL format such as www.domain.com/<userName> and load the component ShowProfile. I want to ensure that terms is not mistaken for a username, so if I visit www.domain.com/terms, I do not want to load ...

The parameter type 'string | null' cannot be assigned to the argument type 'string'. The type 'null' is not compatible with the type 'string'.ts(2345)

Issue: The parameter type 'string | null' is not compatible with the expected type 'string'. The value 'null' is not a valid string.ts(2345) Error on Line: this.setSession(res.body._id, res.headers.get('x-access-token&ap ...

What's the significance of & in TypeScript and JavaScript?

While exploring someone else's code, I came across this interesting piece related to the props of a React component. Although I'm aware that & is typically used as an AND logical operator, it seems to have a different significance in this con ...

Invoke the REST API when a checkbox is selected

I have a React component that I need help with: import * as React from 'react'; import './Pless.css'; interface Props { handleClose: () => void; showPless: boolean; } export class Pless extends React.Component<Props> ...

How can we create external labels for a polar chart in ng2-charts and chart.js, with a set position outside the circular rings?

Currently, I am working on creating a polar chart using Angular along with chart.js version 2.8.0 and ng2-charts version 2.3.0. In my implementation, I have utilized the chartjs-plugin-datalabels to show labels within the polar chart rings. However, this p ...

Ambiguous typing: Element is implicitly considered to be of type 'any' due to the absence of an index signature for type 'Window'

I'm attempting to develop a Factory class in Typescript, however I've encountered the following issue: src/ts/classes/Factory.ts(8,10): error TS7017: Element implicitly has an 'any' type because type 'Window' has no index s ...

Bringing Typescript classes into React-scripts does not act as a constructor

I am currently working on integrating a Typescript file into my existing app using Yarn and React-scripts. Encountered error: Module not found, unable to resolve './DiamondNodeModel' import {DiamondNodeModel} from './DiamondNodeModel&ap ...

Troubleshooting Date library timezone problems in Typescript locale

The TZ variable is automatically set by Node as an environment variable. When using new Date(); in TypeScript, the date returned is in GMT+0000 even though the code is being executed on a machine with a timezone of GMT+0530. I attempted to print out conso ...

Exploring the potential of integrating Imgur API with Angular4

I'm currently in the process of developing a web application using Angular, and I'm encountering difficulties with the Imgur API integration. My main objective is to create a form where users can select their photos, which will then be uploaded t ...

Ensuring a precise data type in a class or object using TypeScript

I am familiar with Record and Pick, but I struggle to grasp their proper usage. My goal is to ensure that a class or object contains specific data types such as strings, Booleans, arrays, etc., while also requiring properties or fields of Function type. in ...

What is the method to incorporate type hints for my unique global Vue directives?

When I import or create a directive in an SFC file, I can receive TypeScript hints like this: import vFocus from 'my-custom-component-library'; View demo with ts hints However, if I globally register it in main.ts, the type hints are not availa ...

Implementing Typescript for managing state in React components

Currently, I have a state set up like this: const [newInvoice, setInvoice] = useState<InvoiceType | null>(invoice) The structure of my InvoiceType is as follows: customer_email: string customer_name: string description: string due_date: stri ...

What is the correct way to initialize an object in Angular 5?

I am in the process of developing a dynamic questionnaire service that utilizes a dynamic form approach. The structure consists of a question base followed by various types of questions such as textboxes, dropdowns, etc. My next step was to create a quest ...

On the subsequent iteration of the function, transfer a variable from the end of the function to the beginning within the same

Can a variable that is set at the end of a function be sent back to the same function in order to be used at the beginning of the next run? Function function1 { If(val1.id == 5){ Console.log(val1.id val1.name) } else{} Val1.id = 5 Val1.name = 'nam ...

Changing a "boolean bit array" to a numerical value using Typescript

Asking for help with converting a "boolean bit array" to a number: const array: boolean[] = [false, true, false, true]; // 0101 Any ideas on how to achieve the number 5 from this? Appreciate any suggestions. Thanks! ...