打字稿:通用反应组件上儿童的类型推断

给定一个在两个属性上是通用的react组件, load 函数返回类型 T ,子节点(这是一个带有 T 类型参数的函数)...

class Test<T> extends React.Component<{
  load: () => T;
  children: (r: T) => JSX.Element;
}> {
  render() {
    return this.props.children(this.props.load());
  }
}

typescript无法从 load 的返回值推断出 res 的类型,它默认为 {} 类型 .

<Test load={() => ({ test: 'x' })}>
  {res =>
    <span>
      {res.test}
    </span>}
</Test>;

这是一个错误,还是打字稿无法根据返回值推断 - 因为它看起来像支持JSX子类型的输入 .

编辑:

对于后台,usecase正在创建一个"lazy"组件,该组件接受 load 函数,该函数返回一个解析为某些其他JSX的promise .

回答(1)

3 years ago

我认为问题是您的代码被转换为类似于:

React.createElement(
  Test,
  {load: () => ({ test: 'x' })},
  res =>
    <span>
      {res.test}
    </span>
)

从那种情况可以更清楚地看出,编译器/定义很难正确推断泛型参数 . 在您的情况下,提示编译器就足够了:

<Test load={() => ({ test: 'x' })}>
    {(res: { test: string }) =>
        <span>
            {res.test}
        </span>}
</Test>