一个相对简单的问题,但是我一直以各种形式碰到这个问题。
这是一个示例(使用try-flow进行测试):
import * as React from 'react';
type Props = {
value: string | number
}
export default class Example extends React.Component<Props> {
_hiddenInput: { current: React.ElementRef<'input'> | null };
value(val: number) {
if (this._hiddenInput.current !== null) {
this._hiddenInput.current.value = String(1234);
}
}
}
这里的_hiddenInput.current
是一个"maybe-type"对象的属性,如果使用if-not-null检查,似乎无法正确地完善它。
你们将如何解决这个问题?
答案 0 :(得分:0)
这是因为Flow不知道String
函数可能会有什么副作用,因此在调用this._hiddenInput.current !== null
时String(1234)
的优化无效(这在赋值之前发生)。考虑这个人为的例子:
export default class Example extends React.Component<Props> {
_hiddenInput: { current: React.ElementRef<'input'> | null };
value(val: number) {
if (this._hiddenInput.current !== null) {
this._hiddenInput.current.value = String(1234);
}
}
}
const example = new Example();
example._hiddenInput = { current: elementRef };
window.String = function(input) {
example._hiddenInput.current = null;
return `${input}`;
};
// Throws, because the String-function above will be called between
// refining the nullable type and assigning to it.
example.value(1)
您可以用Flow知道没有副作用的东西替换函数调用
this._hiddenInput.current.value = `${1234}`
或者您可以在将容器对象分配给其属性之前将其“安全”到局部变量中
const {current} = this._hiddenInput
if (current !== null) {
current.value = String(1234);
}
请参阅文档中的Refinement Invalidations。
当然,String
函数不会实际上做类似的事情,但是目前Flow没有任何了解这一点的方法。有一种feature request用于将函数标记为 pure 的方法,有一天可能会有所帮助。