【问题标题】:Typescript: type inference for children on generic react component打字稿:通用反应组件上的儿童类型推断
【发布时间】:2018-01-13 13:39:27
【问题描述】:

给定一个对两个属性通用的反应组件,一个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 子项的类型是受支持的。

编辑:

对于背景,用例正在创建一个“惰性”组件,它接受 load 函数,该函数返回一个解析为进一步 JSX 的承诺。

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:

    更新: 与此同时,TypeScript 得到了改进,因此问题中给出的代码会自动推断 res 的类型。我还没有检查是哪个更改造成的,但我猜它发生在 3.0-3.3 左右的某个地方。


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

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

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

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

    【讨论】:

    • 好点子,也许 TS 将来会为这些东西添加一些 JSX 特定的类型支持。
    • 我刚遇到这个问题,我想这样做,我不必手动指定孩子的类型,有没有办法推断这个现在请使用最新版本的 TypeScript?
    • 我刚刚检查过,至少通过使用 Typescript 3.3 问题中的代码有效,自动推断 res 的类型。
    • 由于某种原因,当您向加载方法添加参数时它不起作用:&lt;Test load={({ test })=&gt;({ test1: test })}&gt;{({ test1 })=&gt;(&lt;span&gt;{test1}&lt;/span&gt;)}&lt;/Test&gt; 声明测试组件之外的test1 的类型为any...grrr!
    • 但是您使用不同类型的负载?因为第一个(() =&gt; T)没有函数参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-03
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 2018-08-12
    相关资源
    最近更新 更多