确定TS 2.4中的动态模块类型

时间:2017-08-08 13:17:09

标签: typescript

我非常喜欢TS 2.4中新的动态模块支持,尽管我遇到了这个小问题:

当使用import()。then(...)时,给出了模块的类型。如果我需要存储承诺以供日后使用,我无法为Promise生成一个传递模块类型信息的类型参数。

我试图在包装器反应组件(我应该使用react-router v4)中进行动态加载,我想在构造函数中开始加载 - 并在首次安装组件时重新加载。有一个"闪烁"这个问题,但除此之外还有效:

import * as React from 'react'

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

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

    componentDidMount() {
        // Promise<any> makes 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 // PROBLEM: "any", not module type.

    render() {
        return this.myContent
    }
}

任何知道如何输入承诺以使其保持正确类型的动态模块的人?

2 个答案:

答案 0 :(得分:1)

虽然我认为目前不能使用typeof import('./Dashboard')这样的内容,但您可以创建一个更高阶的组件,将componentDidMount中的内容分解出来,同时保留导入的类型

将输入如下:

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

并像这样使用:

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

答案 1 :(得分:0)

我想出了一个方法,虽然丑陋:

通过将加载分离为函数,我们可以使用wicked way to get return type from function方法来获取类型。然后我们得到:

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

IDashboardModule是一种可用于键入成员变量的承诺类型。

更新: 使用 TS 2.8 ,您只需执行ReturnType<typeof loadDashboard>即可省去虚拟函数调用。查看ReturnType的定义,这很棒。