【发布时间】:2021-11-11 15:05:29
【问题描述】:
我一直在解决一个问题,即为组件创建抽象出一些逻辑,以减少大量重复。作为其中的一部分,我有一个通用的Builder 组件,我用它来根据提供的道具动态渲染组件。
问题在于我将元素定义为类似于以下内容:
type InputMap = typeof INPUTS
const INPUTS = {
text: {
component: TextInput,
controlled: false
},
select: {
component: Select
controlled: true
}
}
// Props for TextInput component
type TextProps = {
onChange: (e: ChangeEvent<HTMLInputElement>) => void
onBlur: (e: ChangeEvent<HTMLInputElement>) => void
}
// Props for Select component
type ElementProps = {
onChange: (value: string) => void
onBlur: () => void
}
我想以类似于以下的格式传递我的字段:
const fields = [
{
input: "text",
props: {
onChange: e => console.log(e.target.value)
}
},
{
input: "select",
props: {
onChange: value => console.log(value)
}
}
]
这是我想出的类型:
import { ComponentProps } from "react";
export type FieldConfig<T extends FieldValues, K extends keyof InputMap> = {
input: K;
props?: ComponentProps<InputMap[K]["Component"]>
};
但是在我的Builder 组件中,渲染组件时出现问题。
<div>
{ fields.map(({ input, props }) => {
const { Component, controlled } = INPUTS[input]
return <Component {...props} /> // ERROR HERE
})}
</div>
const { input, props } = field
TypeScript 在这一点上给了我以下错误:
Types of property 'onBlur' are incompatible.
Type 'ChangeHandler' is not assignable to type '() => void'
在这种情况下,我有什么办法可以将类型从联合缩小到该联合的特定实例?我正在尽力避免这里的任何类型断言。任何帮助将不胜感激!
【问题讨论】:
标签: javascript reactjs typescript typescript-generics