我有一个元素类型被参数化的组件。我想输入此组件,以便您可以指定元素的类型并将道具限制为该类型。
interface IProps<T> extends T {
elementName: string,
}
class Foo<T> extends React.Component<IProps<T>, {}> {
render() {
const { elementName, ...props } = this.props;
return React.createElement(elementName, {
...props,
});
}
}
例如,href
当props的类型为时,它是一个有效的prop,AnchorHTMLAttributes
而当它的类型为时,则为有效HTMLAttributes
。
// Ok
<Foo<AnchorHTMLAttributes<AnchorHTMLElement>> href="foo.com"/>
// Type checker error because `href` is not an attribute of a div
<Foo<HTMLAttributes<HTMLDivElement>> href="foo.com"/>
这可能吗?如果可以,怎么办?
看起来您想要的类型是:
React.InputHTMLAttributes<HTMLInputElement>
将两者都换成Input
其他类型的标签。
看起来最通用的约束是:
React.HTMLAttributes<HTMLElement>
然后,您可以将该类型与可以为您提供服务的内容进行合并elementName
。有了约束,elementName
您将获得:
function Foo<T extends React.HTMLAttributes<HTMLElement>>(
props: T & { elementName: string },
) {
const { elementName, ...otherProps } = props
return React.createElement(elementName, otherProps)
}
或作为类组件:
class Foo<T extends React.HTMLAttributes<HTMLElement>> extends React.Component<
T & { elementName: string }
> {
render() {
const { elementName, ...otherProps } = this.props
return React.createElement(elementName, otherProps)
}
}
用法就像您期望的那样工作,尽管您必须提供elementName
。
function App() {
return <>
<Foo<React.InputHTMLAttributes<HTMLInputElement>>
elementName="input"
value={1}
/> {/* valid */}
<Foo<React.InputHTMLAttributes<HTMLInputElement>>
elementName="input"
href='/foo/bar'
/> {/* Property 'href' does not exist on type */}
</>
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句