for a project, I want to dynamically render different components. I'll get an array with different types of objects, and when I map over that array I want to render a component based on a prop of that object. I could use an if/else || switch statement, but with more and more different types of objects, these statements would be very long, so I want to use a different approach, meaning use the prop as a key of an object, which then defines the component which should get rendered.
App.tsx
import instructions, { Instruction } from "./instructions";
import products, { Product } from "./products";
// COMPONENTS
interface ProductCompProps {
content: Product;
}
const ProductComponent: React.FC<ProductCompProps> = ({ content }) => {
return <h1>Product Component: {content.name}</h1>;
};
interface InstructionCompProps {
content: Instruction;
}
const InstructionComponent: React.FC<InstructionCompProps> = ({ content }) => {
return <h1>Product Component: {content.label}</h1>;
};
//
const datas = [...products, ...instructions];
interface Components {
[key: string]: React.FC<ProductCompProps> | React.FC<InstructionCompProps>;
}
const components: Components = {
ProductComponent,
InstructionComponent,
};
const App: React.FC = () => {
return (
<div>
{datas.map((data) => {
const Component = components[data.component];
return <Component content={data} />;
})}
</div>
);
};
export default App;
products.ts
export interface Product {
id: string;
name: string;
component: string;
}
const products: Product[] = [
{
id: "1",
name: "Product name One",
component: "ProductComponent",
},
{
id: "2",
name: "Product name Two",
component: "ProductComponent",
},
];
export default products;
instructions.ts
export interface Instruction {
id: string;
label: string;
component: string;
}
const instructions: Instruction[] = [
{
id: "1",
label: "Product name One",
component: "InstructionComponent",
},
{
id: "2",
label: "Product name Two",
component: "InstructionComponent",
},
];
export default instructions;
So this custom component "Component" could be one of X components, each with its own props.
But Typescript is giving me the following error for the content prop:
Type 'Product | Instruction' is not assignable to type 'Product & Instruction'.
Type 'Product' is not assignable to type 'Product & Instruction'.
What I understand ist, that you can only index an object with certain types, like string or number. In my case when I set a string key:
interface Components {
[key: string]: React.FC<ProductCompProps> | React.FC<InstructionCompProps>;
}
the indexing is working, but then I can't understand why the compiler is mixing the types of the component prop...
I would be very thankful for any help. Please understand that I'm very new to typescript, so I still struggle with generics and advanced typescript stuff.
anytype if types are random in each object?