我想使用类型(或接口)来扩展 React 组件。
定义:
type CoreProps<T> = {
htmlElement?: 'article' | 'aside' // ...
} & React.HTMLAttributes<T>
所需用途:
type MyComponentProps = {
myComponentFirstProp: string
// ...
}
const MyComponent = ({
htmlElement,
myComponentFirstProp,
...props
}: MyComponentProps & CoreProps): JSX.Element => {
// ...
}
我知道我可以用 <T>
替换 HTMLElement
但有没有办法根据 CoreProps
中传递的输入 htmlElement
输入 MyComponent
?>
答案 0 :(得分:0)
有JSX.IntrinsicElements
类型可以获取相关的HTMLAttributes
,所以可以通过这种方式获取。
interface CoreProps<T> {
htmlElement: T;
}
interface MyComponentProps {
myComponentFirstProp?: string;
}
const MyComponent = <T extends keyof JSX.IntrinsicElements>(
props: CoreProps<T> & JSX.IntrinsicElements[T] & MyComponentProps
): JSX.Element => {
...
};
<MyComponent htmlElement="img" src="." />; // OK
<MyComponent htmlElement="a" href="." />; // OK
<MyComponent htmlElement="article" />; // OK
<MyComponent htmlElement="a" src="." />; // Error, no 'src' attribute in <a> element
如果你想要相应类型的属性
import { DetailedHTMLFactory, ReactHTML } from 'react';
type EleAttributes<
T extends keyof ReactHTML
> = ReactHTML[T] extends DetailedHTMLFactory<infer R, infer P> ? R : never;
EleAttributes<'input'>
EleAttributes<'aside'>
...
基于你的例子:
type CoreProps<T extends keyof JSX.IntrinsicElements> = {
htmlElement?: T;
} & JSX.IntrinsicElements[T];
type ComponentProps = {
display?: string;
};
const Component = <T extends keyof JSX.IntrinsicElements>({
htmlElement,
display,
style,
children,
...props
}: ComponentProps & CoreProps<T>) => {
const styles = {
...style,
display,
// more ...
};
// Set default 'div' when htmlElement is undefined
return React.createElement(
htmlElement || 'div',
{
style: styles,
...props,
},
children
);
};