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
};