1

在我的 React 应用程序中,我使用Unstated来管理共享状态,但是我在使用 TypeScript 时遇到了问题:<Subscribe>组件向我传递了一个类型为Container<any>. 这意味着它需要转换为我自己的类型,例如Container<MyState>,在我可以安全地使用它之前。

相反,如果我希望 Unstated 将我的容器的已键入实例传递给我,我应该如何包装和/或分叉Unstated 源和/或其类型文件,以便当我获取Container实例时,它的类型为Container<MyState>

顺便说一句,我想要获得传入的类型化容器的特殊原因是,我可以使用复杂状态的解构,而不必切换到使用更冗长的胖箭头函数的块形式。

这是我希望能够编写的代码的简化示例:

function Counter() {
  return (
    <Subscribe to={[CounterContainer]}>
      {({increment, decrement, state}) => (
        <div>
          <button onClick={() => decrement()}>-</button>
          <span>{state.count}</span>
          <button onClick={() => increment()}>+</button>
        </div>
      )}
    </Subscribe>
  );
}

这是我当前的编写方式,在使用 TypeScript 的简化未说明示例中:

import React from 'react';
import { render } from 'react-dom';
import { Provider, Subscribe, Container } from 'unstated';

interface CounterState {
  count: number
};

class CounterContainer extends Container<CounterState> {
  public state = {
    count: 0
  };

  public increment() {
    this.setState({ count: this.state.count + 1 });
  }

  public decrement() {
    this.setState({ count: this.state.count - 1 });
  }
}

function Counter() {
  return (
    <Subscribe to={[CounterContainer]}>
      {(counter: CounterContainer) => {
        const {increment, decrement, state} = counter;
        return (
          <div>
            <button onClick={() => increment()}>-</button>
            <span>{state.count}</span>
            <button onClick={() => decrement()}>+</button>
          </div>
        )
      }}
    </Subscribe>
  );
}

render(
  <Provider>
    <Counter />
  </Provider>,
  document.getElementById('root')
);
4

1 回答 1

2

因此,查看最初添加打字稿定义的 PR,注意到他们无法找到一种方法来自动提供您正在寻找的打字,因为像 $TupleMap这样的东西在 TS 中不存在,就像它在 Flow 中一样,而您必须手动提供输入。

如果您的主要动机是避免使用箭头函数的额外 {},您可以手动提供输入并仍然执行相同的解构。所以从你的例子中:

function Counter() {
  return (
    <Subscribe to={[CounterContainer]}>
      {({increment, decrement, state}: CounterContainer) => (
          <div>
            <button onClick={() => increment()}>-</button>
            <span>{state.count}</span>
            <button onClick={() => decrement()}>+</button>
          </div>
        )
      }
    </Subscribe>
  );
}

也可以。也许有一种方法可以在 Typescript 中自动输入,但这超出了我的范围。

于 2018-09-15T23:15:33.577 回答