Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

104
Views
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

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

You can use a mapped type to emulate what you are doing in the function code

type WithId<T> = {
    [P in keyof T]: 
      T[P] extends Function ? T[P] :
      T[P] extends object ? WithId<T[P]>:
      T[P] 
} & {
    id: string
}
export const withIds = <T extends Record<string, any>>(copyObject: T, initialId: string) =>
  new Proxy(copyObject, createHander([initialId])) as unknown as WithId<T>

Playground Link

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!