【问题标题】:Flow generics in react component props反应组件道具中的流泛型
【发布时间】:2018-11-01 13:20:16
【问题描述】:

我正在尝试使用泛型键入组件的道具,但流程没有捕捉到错误。基本上,我想要一个有两个道具fetchcb 的组件。无论fetch返回什么类型,都应该是cb的返回类型。

// @flow
import React, { Component } from 'react';

type Props<T> = {
  fetch: () => Promise<T>,
  cb: T => T,
};

class Client<T> extends Component<Props<T>> {

  componentDidMount() {
    const { fetch, cb } = this.props;
    fetch().then(cb);
  }

  render() {
    return (<div />)
  }
}
        
const App = () => (
  <Client
    fetch={ () => Promise.resolve(1) } 
    cb={ n => 'sfd' } />
 );

在底部,我将一个函数传递给fetch,该函数解析为number,但cb 返回一个string,并且没有流错误。为什么?

这里是repl

这甚至不是react 的事情。一个简单的函数将无法检查类型:

const fun = <T>(a: () => T, b: T => T): T => b(a());
fun(() => 2, n => 'qwe');

【问题讨论】:

  • this 看来流需要cb 参数的类型
  • 附上 Alex 的评论:Flow 似乎将 cb 道具的类型推断为 (string | number) =&gt; number。这就是为什么它“需要”为 cb arg 指定的类型。
  • 好吧,我使用泛型来避免定义具体类型:) 这是非常基本的类型检查。

标签: javascript reactjs flowtype


【解决方案1】:

在功能的情况下你错了。它应该分配给一个变量:

function f<T>(a: () => T, b: T => T): T {
    return b(a());
}

const r: number = f(() => 2, n => ""); // error

try it

但是在组件道具的情况下......也许它期望被参数化,但我找不到参数化组件的方法。

【讨论】:

  • 对此,您需要指定r: number 的原因是Flow 认为从您的函数返回string | number 是完全可以接受的。我不太确定这是最好的解释,但它就是这样。
【解决方案2】:

正如 James Kraus 在评论中所说,流程是在推断您的 T 类型是 number|string。没有什么可以阻止泛型成为求和类型,除非您限制其中一个函数或使用具体类型对泛型函数进行参数化,否则流程将继续推断求和类型。

非常接近基里尔写的,但也许更容易理解限制来自哪里:

function f<T>(a: () => T, b: T => T): T {
    return b(a());
}
        
const r = f<number>(() => 2, n => "");

这里你会在第二个函数中得到一个错误,因为我们已经告诉了 flow

这个泛型必须是数字,强制执行!

然后它就完成了它的工作。

【讨论】:

    猜你喜欢
    • 2020-04-08
    • 2021-04-24
    • 2018-10-09
    • 1970-01-01
    • 2019-01-08
    • 2020-12-25
    • 2019-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多