我试图在react+typescript中创建动态组件,但我很难正确地在上面键入道具。
这是我正在做的事情的一个简单版本。
interface ComponentProps {
title: string;
}
interface ArrInterface {
component: FC<ComponentProps>;
title: string
}
const Arr: ArrInterface = [
{ component: FooComponent, title: "foo"},
{ component: FooComponent, title: "bar"}
];
const FooComponent: FC<ComponentProps> = ({title}) => {
return <div>{title}</div>
}
const BarComponent: FC = () => {
return sectionsArr.map((section) => {
const {component, title} = section;
return React.createElement(component as FC, { title })
})
}
这就是我得到的错误:
类型为"{title:string;}"的参数不可分配给类型为"Attributes"的参数
对象文字只能指定已知的属性,并且类型"Attributes"中不存在"title">
如果我在那行的顶部忽略ts,它就会起作用btw:(
有人能帮我解决这个问题吗?我在这里错过了什么?
我自己找到了解决方案:(
对于那些最终出现与我相同问题的人,您需要将props类型传递给createElement函数。
所以基本上不做
return React.createElement(component as FC, { title })
这应该可以解决问题
return React.createElement<ComponentProps>(component as FC, { title })
TS用于React.createElement
的签名是
function createElement<P extends {}>(
type: FunctionComponent<P>,
props?: Attributes & P | null,
...children: ReactNode[]): FunctionComponentElement<P>;
在React.createElement(component as FC, { title })
调用中,传递一个类型为FC
的值(component
(作为名为type
的参数。FC
定义为
type FC<P = {}> = FunctionComponent<P>;
因此,由于您断言了component as FC
——没有类型参数——TS现在使用类型参数P
的默认类型,即{}
。现在props
参数的类型是Attributes & {}
,这与Attributes
的类型相同。就像TS告诉你的那样,属性"title"在类型"Attributes"中不存在。