I have 3 components, Grid, BlockWrapper, and Block.
Block is a children of BlockWrapper.
Block has the props blockClassName and text, which I specified in an interface:
Grid/index.tsx
const blockWrappers:Array<JSX.Element> = [];
const blocks:Array<JSX.Element> = [];
// ...
for(let i = 0; i < 16; i ) {
blocks.push(
<Block
blockClassName={ blockClassName }
text={i ""}
/>
);
blockWrappers.push(
<BlockWrapper index={i} >
{ blocks[i] }
</BlockWrapper>
)
}
// ...
interface BlockProps {
blockClassName: string,
text: string
}
swappable.on("swappable:swapped", () => {
for(let wrapper of blockWrappers) { // blockWrappers is an array of BlockWrapper
let child = wrapper.props.children as React.FunctionComponent<BlockProps>; // Getting child of BlockWrapper, which is Block
if(child.blockClassName) console.log(); // Error: Property 'blockClassName' does not exist on type 'FunctionComponent<BlockProps>'.ts(2339)
}
updateClasses();
});
Block/index.tsx
const Block = ( {blockClassName, text}: {blockClassName: string, text: string} ) => {
if(blockClassName.includes("isEmpty")) text = "";
return (
<span className={blockClassName}>
<Content>
<h1>{text}</h1>
</Content>
</span>
);
}
However, when I try to access blockClassName from child, which is a FunctionComponent, it gives me an error saying the property "blockClassName" does not exist in child. I already specified in BlockProps that it has a property called "blockClassName," and I don't see why the error is showing up. How can I fix this?
Thanks in advance.
CodePudding user response:
In what you've shown, blockWrappers
is an array of React.ReactElement
, each with a single child. That's not React.FunctionComponent<BlockProps>
, which is a function type, it's React.ReactElement<BlockProps>
.
You can access that single child via React.Children.only
(if there were more, you'd use one of the other methods on React.Children
)):
const child = React.Children.only<React.ReactElement<BlockProps>>(wrapper.props.children);
and then just as with the wrapper, you need to use .props
to see the child's props:
console.log("blockClassName = ", child.props.blockClassName);
E.g.:
for (const wrapper of blockWrappers) {
const child = React.Children.only<React.ReactElement<BlockProps>>(wrapper.props.children);
if (child.props.blockClassName) {
console.log("blockClassName = ", child.props.blockClassName);
}
}
Playground link showing the types (a simplified version I created before your edit)