如何在 Typescript 2.8 中使用 Flux Container.create

How to use Flux Container.create in Typescript 2.8

我正在尝试将我的 react/flux 项目从 typescript 2.2 更新到 2.8。

我使用 container.create 效用函数定义商店:

import * as React from 'react';
import { Container } from 'flux/utils';

export let MyContainer = Container.create(class extends React.Component<props, state> {
    static getStores() {
        return [/* list of stores here*/]
    }

    static calculateState(prevState: state, props: props): state {
        return {hello: true}
    }

    render() {
        return <div>something</div>
    }
}, { withProps: true });

如果我导出这个组件并尝试使用它,我会收到以下错误:

TS2605: JSX element type 'Component<props, ComponentState>' is not a constructor function for JSX elements.

这在我使用 typescript 2.2 时工作正常,但在更新后我到处都出错,我尝试像这样使用容器组件。

我使用的是@types/react 打字版本 15.0.28。 Here are the definitions for Flux Containers.

显然从 typescript 2.6 开始会出现此错误。但我不确定是什么破坏性变化导致了这种行为,none 似乎 match

根本原因是这样的:

let readOnlyOrVoid: Readonly<void | {}> // resolves to void | Readonly<{}>
let readOnlyOfAny: Readonly<any> // in 2.5 this resolves to any, in 2.6 it does not we still have Readonly<any>
readOnlyOfAny = readOnlyOrVoid; // valid in 2.5, not so in 2.6

关于 ReactComponentState 在 15.0.23 中定义为:

type ComponentState = {} | void ;

JSX.ElementClass(扩展 React.Component<any, any>)的 state 的类型为 Readonly<any>

因为 Container.create 将 return 一个状态为 ComponentState 的包装组件,我们 运行 正好进入这个分配 Readonly<void | {}> 的问题(来自包装组件) 到 Readonly<any> (来自 JSX.ElementClass 的定义)

最简单的解决方案是将 react 的类型更新为 15.0.39,从而将 ComponentState 的定义替换为:

type ComponentState = {};