Álvaro
Álvaro

Reputation: 2588

TypeScript types for heavily nested object

I got a tree I am trying to render recursively

The tree variable is just an example it could grow much bigger depending on the data the app gets.

How can I keep TypeScript happy about the types on this tree even thou I don't know how nested is going to get?


const tree = {
  people: ['Managing Director'],
  children: {
    people: ['Operations Director', 'Head of Client Services'],
    children: {
      people: ['Senior Developer']
    }
  }
}

interface IList {
  people: string[],
  children: string[]
}

interface IData {
  data: IList[]
}

const List: FC<IData> = ({ data }) => (
  <ul>
    {data.people.map((person) => ( <li>{person}</li> ))}
    {!data.children ? null : <List data={data.children} />}
  </ul>
)

function App() {
  return (
    <>
      <List data={tree} />
    </>
  )
}

When I do it on codesandbox it works but with warnings, If I do it on my config I get

`Property 'people' does not exist on type 'IList[]'`

EXAMPLE

Upvotes: 5

Views: 1604

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370809

You need to make the children property optional and a recursive type:

type Tree = {
    people: Array<string>;
    children?: Tree;
}

const tree: Tree = {
  people: ['Managing Director'],
  children: {
    people: ['Operations Director', 'Head of Client Services'],
    children: {
      people: ['Senior Developer']
    }
  }
}

Then List can accept a prop of type Tree and recursively render it.

const List = ({ data }: { data: Tree }) => (
    <ul>
        {data.people.map((person) => (<li>{person}</li>))}
        {!data.children ? null : <List data={data.children} />}
    </ul>
)

Upvotes: 6

Related Questions