I have some component that can render data of any object, so I use generic here, but I have some
problems here
{field} : {el[field]}
What is correct way handle this in my example
https://codesandbox.io/s/sleepy-thompson-gim2d1?file=/src/App.tsx
I know that we can use something like this {field} : {el[field as SomeInterface]}
or just
add some record property into interface, but I still have problem(
You can see my code in the link above, and I also leave it here.
type WrapperProps<T> = {
data: T[];
};
function Wrapper<T extends object>({ data }: WrapperProps<T>) {
return (
<div>
{data.map((el) => {
return Object.keys(el).map((field) => {
return (
<div key={el field}>
{field} : {el[field]} // type error here
</div>
);
});
})}
</div>
);
}
interface IData {
name: string;
age: number;
}
interface IData2 {
email: string;
passport: string;
}
export default function App() {
const data1: IData[] = [
{ name: "Alex1", age: 133 },
{ name: "Alex2", age: 33 }
];
const data2: IData2[] = [
{ email: "email", passport: "passport1" },
{ email: "email2", passport: "passport2" }
];
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<Wrapper data={data1} />
<hr />
<Wrapper data={data2} />
</div>
);
}
CodePudding user response:
Change the compilerOptions/lib in tsconfig.json to "es2017", and use Object.entries()
that will extract the value directly (sandbox):
{data.map((el) => {
return Object.entries(el).map(([field, value]) => {
return (
<div key={el field}>
{field} : {value}
</div>
);
});
})}
Note: the expression el field
would result in "[object object]" the text of the field, so the key won't be unique. You should probably use specific value of each object (id
for example) as a basis for the key. Furthermore, you should also use Array.flatMap()
to get a single array, and not array of arrays. You can also remove redundant returns, since you're using arrow functions:
{data.flatMap(el => Object.entries(el).map(([field, value]) => (
<div key={`${el.id}-${field}`}>
{field} : {value}
</div>
)))}