我非常喜欢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
}
}
任何知道如何输入承诺以使其保持正确类型的动态模块的人?
答案 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
的定义,这很棒。