'Strongly type a recursively nested proxy

I have some objects that I store content for some UI. They look like this:

const copy = {
  header: {
    content: 'Page Header'
  },
  main: {
    header: {
      content: 'content sub header'
    }
    body: {
      content: 'lorem ipsum....'
    }
    dynamic: {
      content: (data: string) => `some ${data}`
    }
  }
}

I have written a proxy which lets me get an ID, generated by the deeply nested path of the content I am accessing:

const isObject = (obj: unknown): obj is Record<string, any> =>
  typeof obj === 'object' && obj != null

const createHander = <T extends Record<string, any>>(path: string[]) => ({
  get: (target: T, key: string): any => {
    if (key === 'id') {
      return path.join('-')
    }
    const newTarget = target[key]
    if (isObject(newTarget)) {
      return new Proxy(newTarget, createHander([...path, key]))
    }
    return newTarget
  },
})

export const withIds = (copyObject: Record<string, any>, initialId: string) =>
  new Proxy(copyObject, createHander([initialId]))

so the following is true:

const copyWithIds = withIds(copy, 'page')
copyWithIds.main.body.id // page-main-body

Trouble is, everything on the copyWithId's object is now of type any

I would like to not be reliant on the any type as the return of the get but struggling to find a set up that works



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source