【发布时间】:2021-10-19 12:47:05
【问题描述】:
我想使用 TypeScript 在 React 组件上强制执行属性,但我遇到了奇怪的行为。下面我只粘贴简单的例子:
function FunctionalComponent(props: { color: string }) {
return <></>;
}
type ComponentWithName<I extends React.FunctionComponent<{ name: string } & React.ComponentProps<I>>> = I;
const component: ComponentWithName<typeof FunctionalComponent> = FunctionalComponent;
即使我声明组件必须具有属性名称,上面的代码也会通过。使用此代码我需要得到一个错误,因为 FunctionalComponent 不包含 name 属性。
另一方面,这是可行的:
function FunctionalComponent(props: { color: string }) {
return <></>;
}
type ComponentWithName<I extends React.FunctionComponent<{ name: string }>> = I;
const component: ComponentWithName<typeof FunctionalComponent> = FunctionalComponent
这段代码会抛出一个 TypeScript 错误,这正是我所需要的。但问题是,FunctionalComponent 不能有其他属性,除非我手动将它们添加到React.FunctionComponent。
目标是强制组件具有“名称”属性,但允许具有更多附加(未指定)属性。
我正在使用 TypeScript 版本 4.4.4 和 React 版本 17.0.2
编辑:
真正的用例是这样的:
function Component<
I extends
| React.ComponentClass<
{
onChange: (event: React.ChangeEvent) => void;
} & React.ComponentProps<I>
>
| React.ComponentType<
{
onChange: (event: React.ChangeEvent) => void;
} & React.ComponentProps<I>
>
>(
props: {
component?: I;
} & Omit<React.ComponentProps<I>, "onChange">
) {
const { component: Component, ...rest } = props;
const handleChange = () => {
//
};
return (
<div>
{Component ? (
<Component
{...(rest as React.ComponentProps<I>)}
onChange={handleChange}
/>
) : (
<input onChange={handleChange} />
)}
</div>
);
}
class ComponentClass extends React.Component<{
color: "blue" | "yellow";
}> {
render() {
return (
<input style={{color: this.props.color}} />
);
}
}
function ComponentFunction(props: { color: "blue" | "yellow" }) {
return <input style={{color: props.color}} />;
}
function App() {
return (
<>
<Component component={ComponentClass} color="blue" />
<Component component={ComponentFunction} color="blue" />
</>
);
}
<Component component={ComponentClass} color="blue" /> 将引发类型错误,但 <Component component={ComponentFunction} color="blue" /> 不会。我需要强制传递的组件具有指定类型的 onChange 属性。
【问题讨论】:
标签: reactjs typescript