Javascript 迭代HTMLFormElement元素时是否更正流类型?

Javascript 迭代HTMLFormElement元素时是否更正流类型?,javascript,flowtype,Javascript,Flowtype,我有一个函数,它接受表单元素作为输入,过滤它的子元素(删除那些没有可序列化值的元素),然后返回一个{name:value}形式的对象 类型检查似乎失败了,因为Flow告诉我传递给filter函数的每个元素只是一个基本的HTMLElement。我通过检查element.type、element.name等进行筛选,由于HTMLElements没有这些属性,因此出现错误 这两个过滤函数使用一个联合类型来进行类型检查,该联合类型包含我希望存在的相关元素(HTMLInputElement,HTMLTex

我有一个函数,它接受表单元素作为输入,过滤它的子元素(删除那些没有可序列化值的元素),然后返回一个
{name:value}
形式的对象

类型检查似乎失败了,因为Flow告诉我传递给filter函数的每个元素只是一个基本的
HTMLElement
。我通过检查
element.type
element.name
等进行筛选,由于
HTMLElement
s没有这些属性,因此出现错误

这两个过滤函数使用一个联合类型来进行类型检查,该联合类型包含我希望存在的相关元素(
HTMLInputElement
HTMLTextAreaElement
等)。他们自己完成这些工作。只有在过滤器中调用它们时,我才会得到错误

模块的完整代码为:

/* @flow
 * Returns form data as a javascript object. Requires each
 * form element to have a name that corresponds to its value.
 */
type FormChild =
  | HTMLInputElement
  | HTMLSelectElement
  | HTMLTextAreaElement
  | HTMLButtonElement
  | HTMLFieldSetElement;

const isValidTarget = (el: FormChild): boolean => {
  return !(el instanceof HTMLFieldSetElement) &&
         !(el instanceof HTMLButtonElement) &&
         el.name !== '';
};

const isSerializable = (el: FormChild): boolean => {
  return (el.type === 'radio' && el.checked === true) ||
         (el.type === 'checkbox' && el.checked === true) ||
         (el.type !== 'radio' && el.type !== 'checkbox');
};


export default (form: HTMLFormElement): { [elementName: string]: string } => {
  return [...form.elements].filter((el) => isValidTarget(el) && isSerializable(el))
                           .reduce((data, el) => ({ [el.name]: el.value, ...data }), {});
};
我得到的所有错误都与过滤器中的调用有关:

HTMLElement此类型与联合不兼容:HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | htmlButtoneElement | HTMLFieldSetElement

并与
reduce
相关:

在HtmleElement中找不到属性“name”属性

在HtmleElement中找不到属性“值”属性有两个步骤:

  • 将类型从
    HTMLElement
    转换为
    FormChild
  • FormChild
    类型中删除
    HTMLFieldSetElement
    ,因为它不能具有
    value
    属性,并将使用
    isValidTarget()进行筛选
/*@flow
*将表单数据作为javascript对象返回。需要每个
*表单元素的名称与其值相对应。
*/
类型FormChild=
|HTMLInputElement
|HTMLselect元素
|HtmlTextArea元素;
//|HTMLButtoneElement{
返回值(el.type=='radio'&&el.checked===true)||
(el.type=='checkbox'&&el.checked===true)||
(el.type!=='radio'和&el.type!=='checkbox');
};
导出默认值(格式:HTMLFormElement):{[elementName:string]:string}=>{
//`el:any`-准备施放
return[…form.elements].filter((el:any)=>isValidTarget(el)和&isSerializable(el))
.reduce((data,el:FormChild)=>({[el.name]:el.value,…data}),{});
//`el:FormChild`-类型已铸造
};

流量测试:4.0.5

谢谢!因为filter函数的输入可以是任何表单元素的子元素,所以我假设需要包含那些将被过滤掉的子元素。你的解决方案很有意义。
/* @flow
 * Returns form data as a javascript object. Requires each
 * form element to have a name that corresponds to its value.
 */
type FormChild =
  | HTMLInputElement
  | HTMLSelectElement
  | HTMLTextAreaElement;
//| HTMLButtonElement         <— removed, will be filtered by isValidTarget()
//| HTMLFieldSetElement;      <— removed, will be filtered by isValidTarget()

    const isValidTarget = (el: FormChild): boolean => {
      return !(el instanceof HTMLFieldSetElement) &&
             !(el instanceof HTMLButtonElement) &&
             el.name !== '';
    };

    const isSerializable = (el: FormChild): boolean => {
      return (el.type === 'radio' && el.checked === true) ||
             (el.type === 'checkbox' && el.checked === true) ||
             (el.type !== 'radio' && el.type !== 'checkbox');
    };


    export default (form: HTMLFormElement): { [elementName: string]: string } => {
//                                     `el: any` — prepare to cast
      return [...form.elements].filter((el: any) => isValidTarget(el) && isSerializable(el))
                               .reduce((data, el: FormChild) => ({ [el.name]: el.value, ...data }), {});
//                                           `el: FormChild` — type was casted
    };