私はReactラッパーコンポーネントを持っています。これはいくつかの小道具を受け入れますが、他のすべてを子コンポーネントに転送します(特に、className、idなどのネイティブ小道具に関連します)。
しかし、ネイティブの小道具を渡すと、TypeScriptは文句を言います。エラーメッセージを参照してください。
TS2339:プロパティ 'className'はタイプ 'IntrinsicAttributes&IntrinsicClassAttributes <Wrapper>&Readonly <{children?:ReactNode; }>&読み取り専用<WrapperProps> '。
ネイティブの小道具も受け入れる特定の小道具を持つコンポーネントを取得するにはどうすればよいですか(小道具を受け入れて型チェックをあきらめることなく)?
私のコードは次のようになります:
interface WrapperProps extends JSX.IntrinsicAttributes {
callback?: Function
}
export class Wrapper extends React.Component<WrapperProps>{
render() {
const { callback, children, ...rest } = this.props;
return <div {...rest}>
{children}
</div>;
}
}
export const Test = () => {
return <Wrapper className="test">Hi there</Wrapper>
}
参考:ここで同様の質問を見つけましたが、答えは基本的に型チェックをあきらめ、避けたいと思います: SOへのリンク-質問
div
小道具がどのように定義されているかを見ることができます。
interface IntrinsicElements {
div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
}
基本タイプとしてReact.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
を使用すると、div
のすべてのプロパティが得られます。 DetailedHTMLProps
はref
をReact.HTMLAttributes<HTMLDivElement>
に追加するだけなので、これを基本インターフェースとして使用して、すべてのdiv
プロパティを取得できます。
interface WrapperProps extends React.HTMLAttributes<HTMLDivElement> {
callback?: Function
}
export class Wrapper extends React.Component<WrapperProps>{
render() {
const { callback, children, ...rest } = this.props;
return <div {...rest}>
{children}
</div>;
}
}
export const Test = () => {
return <Wrapper className="test">Hi there</Wrapper> // works now
}
私の同僚はそれを理解しました。より広い可視性のためにここで共有する:
interface ComponentPropTypes = {
elementName?: keyof JSX.IntrinsicElements; // list of all native DOM components
...
}
// Function component
function Component({
elementName: Component = 'div',
...rest,
// React.HTMLAttributes<HTMLOrSVGElement>) provides all possible native DOM attributes
}: ComponentPropTypes & React.HTMLAttributes<HTMLOrSVGElement>)): JSX.Element {
return <Component {...rest} />;
}
// Class component
class Component extends React.Component<ComponentPropTypes & React.HTMLAttributes<HTMLOrSVGElement>> {
render() {
const {
elementName: Component,
...rest,
} = this.props;
return <Component {...rest} />
}
}