下面的代码有两个问题。
interface MyForm {
age: number;
email: string;
name: string;
}
function Form<
T,
ComponentProps extends {
name: string;
onChange: (event: React.ChangeEvent) => void;
}
>(
props: {
component:
| React.ComponentClass<ComponentProps>
| React.ComponentType<ComponentProps>;
name: keyof T;
} & Omit<ComponentProps, "name" | "onChange">
) {
const { component: Component, name, ...rest } = props;
const handleChange = () => {
//
};
return <Component {...(rest as any)} name={name} onChange={handleChange} />;
}
function Component(props: {
name: string;
onChange: (event: React.ChangeEvent) => void;
color: "blue" | "yellow";
}) {
const { color, name, onChange } = props;
return <input name={name} onChange={onChange} style={{color}} />;
}
function App() {
return (
<>
{/* in this code, the name is not checked */}
<Form color="blue" component={Component} name="something" />
{/* in this code, the name is checked, but I must define all generics */}
<Form<MyForm, React.ComponentProps<typeof Component>>
color="yellow"
component={Component}
name="name"
/>
{/* this doesn't work */}
<Form<MyForm> color="blue" component={Component} name="email" />
</>
);
}
首先,我想像<Form<MyForm> color="blue" component={Component} name="email" />
这样调用Form组件,而不是定义第二个泛型。在一个复杂的组件中,我有更多的属性和泛型,我不想强迫其他程序员定义所有的泛型,只是因为我希望name
必须匹配MyForm
中的键。这就是目标。name
必须通过TypeScript检查,并且必须是MyForm
的keyof,我知道我可以使用可选泛型并定义默认类型,但这违反了逻辑,然后我在调用Form
时无法传递color
,并且我无法定义颜色是必需的,因为逻辑是,component
必须有name
和onChange
属性,剩下的我不关心,把剩下的传递给组件就行了。
第二,我不能去掉{...(rest as any)}
中的any。我不知道,为什么我只使用{...rest}
时会得到一个错误。
2条答案
按热度按时间um6iljoc1#
看起来您在第一个问题中要求的是让
<Form>
组件的用户能够指定 * 一些 * 泛型参数(例如<Form<MyFormInterface> />
),并让typescript仍然推断其余参数(例如传递给component
属性的组件属性)。不幸的是,目前还不支持类型推断-类型推断是一个全有或全无的命题-要么typescript推断所有内容,要么用户指定所有内容。有an extremely popular github issue asking for this exact feature。另请参见this answer以获得更一般的解释。
xmjla07d2#
有一种方法可以定义和导出函数重载