1

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>
  );
}

1 Answer 1

2

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>
)))}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, so with Object,keys there ara no good way to handle it?
As you said, you can cast the field when using it {el[field as keyof T]} - codesandbox.io/s/intelligent-hertz-0pmkcw.
nice, and thanks for key) silly mistake)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.