[英]How to type es6 generators with flow
我的react-native应用程序中有以下(简化的)代码(我认为react-native是无关紧要的,但这是我在其中发现错误的上下文)。
我试图定义mystring
和gen
的类型以保持flow
快乐,但是我发现的唯一解决方案是string|void
,如下所示。 下面的代码本身不会对流返回任何错误,但是一旦在其他地方使用mystring
,我就会收到错误,因为期望使用string
,而不是void
。 我玩过各种各样的组合,但是没有运气。
我应该如何修改此代码以纠正错误?
// @flow
import * as React from 'react';
type State = {
mystring: string|void,
};
type genType = Generator<string, void, void>;
export default class Example extends React.Component<{}, State> {
constructor(props: {}) {
super(props);
this.gen = this.makeGenerator();
const { value } = this.gen.next();
this.state = {
mystring: value,
};
}
gen: genType;
* makeGenerator(): genType {
yield 'somestring';
}
render() {
const { mystring } = this.state;
return mystring.charAt(0);
}
}
在上面的代码上运行flow
时,请在最后一行(这是强制流将mystring
视为字符串的示例):
Cannot call mystring.charAt because property charAt is missing in undefined [1].
[1] 5│ mystring?: string,
对于Generator
引用类型类型参数,如下所示:
interface Generator<+Yield,+Return,-Next>
当您调用next()
您将得到以下类型的结果:
type IteratorResult<+Yield,+Return> =
| { done: true, +value?: Return }
| { done: false, +value: Yield };
您可以看到done: true
情况Flow假设结果中的value
属性可能不存在。 这意味着,无论您如何键入生成器,Flow都会假定在这种情况下value
的类型可能为void
。 但是在done: false
情况下,Flow将使用您指定为生成器的Yield
类型的任何类型。 因此,您可以检查一下done
的值以细化value
的类型,如下所示:
const result = this.gen.next();
if (!result.done) {
this.state = {
mystring: result.value,
};
}
对!result.done
的检查将result
的类型细化为{ done: false, +value: Yield }
,该类型给出value
的类型string
,不可能有void
值。
通过该更改,您可以更新状态类型以从mystring
的类型联合中删除void
:
type State = {
mystring: string,
};
上面Generator
和IteratorResult
的定义来自Flow的标准类型定义,您可以在此处查看:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.