reactjs - 如何为 React.Children.map 定义打字稿
问题描述
我有一个查看提供的子元素的函数,如果找到特定的元素类型,它会自动向它添加一些属性。
该函数是这样调用的:
render () {
const { children, name, className } = this.props;
return (
<div className={className}>
{this.enrichRadioElements(children, name)}
</div>
)
}
它是这样实现的:
enrichRadioElements = (children: Array<any>, name: string) => (
React.Children.map(children, child => {
if (!React.isValidElement(child)) {
return child;
}
//@ts-ignore
if (child.props.children) {
child = React.cloneElement(child, {
//@ts-ignore
children: this.enrichRadioElements(child.props.children, name)
});
}
if (child.type === Radio) {
return React.cloneElement(child, {
onChange: this.handleFieldChange,
selectedValue: this.state.selectedValue,
name: name
})
}
else {
return child;
}
})
)
这两条//@ts-ignore
评论是我试图通过编写满足打字稿的代码来摆脱的。如果我删除第一个,我看到的错误消息是:
类型“{}”上不存在属性“子项”。(ts-2339)
如何正确修改我的代码以便删除//@ts-ignore
评论?我确实去了 child.props 的定义,我发现了这个:
interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
type: T;
props: P;
key: Key | null;
}
它看起来有任何类型的“道具”(如果我没看错的话),但打字稿无法识别 children 属性。
解决方案
问题是几件事。我首先更改children: Array<any>
为children: React.ReactNode
. 您已经在那里进行了检查以将类型从 ReactNode 缩小到 ReactElement。诀窍是 1. 使用泛型类型参数 inisValidElement
和 2. 使用带有类型赋值的新变量,elementType
而不是处理和改变child
参数。EnrichedChildren
可能需要更新以匹配您的用例。
interface EnrichedChildren {
onChange(): void
selectedValue: string
name: string
children?: React.ReactNode
}
enrichRadioElements = (children: React.ReactNode, name: string): any =>
React.Children.map(children, child => {
if (!React.isValidElement<EnrichedChildren>(child)) {
return child
}
let elementChild: React.ReactElement<EnrichedChildren> = child
if (child.props.children) {
elementChild = React.cloneElement<EnrichedChildren>(elementChild, {
children: this.enrichRadioElements(elementChild.props.children, name),
})
}
if (elementChild.type === 'Radio') {
return React.cloneElement(elementChild, {
onChange: () => {},
selectedValue: 'value',
name: name,
})
} else {
return elementChild
}
})
推荐阅读
- entity-framework - EF Core - 不包括二进制字段
- javascript - Angular从父组件获取所有子组件的状态
- python - TypeError:图像数据无法转换为浮点数图像数据无法转换为浮点数
- javascript - 从数据库中获取经度和纬度
- laravel - Laravel:如何为发送电子邮件的通知编写集成测试
- elixir - 如何在 Elixir 中的 Application.start 回调中在指定目录中创建 mnesia 模式?
- ios - 无法使用 SSZipArchive 创建受密码保护的 zip 文件
- javascript - 使用 Reg Ex 传输数据格式
- html - 如何在 Angular Material 中将制表键作为输入键?
- c# - Unity3d - 玩家车道变化顺畅