Flowtype:无法将X分配给Y,因为null中缺少属性Y.

问题描述 投票:1回答:1

一个相对简单的问题,但我不断以各种形式碰撞。

这是一个例子(用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检查似乎没有得到正确的改进。

你们怎么解决这个问题?

javascript flowtype
1个回答
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可以将功能标记为纯粹,有朝一日可能有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.