Home > OS >  How handle with object keys when we type dynamic objects?
How handle with object keys when we type dynamic objects?

Time:04-15

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>
)))}
  • Related