5

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

1
  • 1
    One thing to note about the warning you are getting on codesandbox: it isn't related to the TypeScript issue, it's because when using the an iterator, in your case .map, to render the tags you need a key prop. So in your case: ...(<li key={person}>{person}</li>) will make it happy. (as long as person is unique, if not, just use the index) Commented Jan 30, 2021 at 16:51

1 Answer 1

6

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

1 Comment

I'd remove the FC, IList, and IList types, IMO they aren't doing anything useful for you. Just use the one Tree type for the prop.

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.