Access dynamic second-level property in Typescript object

Florian

I need to access an object property in Typescript for which two levels are dynamic, e.g. object[key1][key2].
Even though I believe I do the appropriate checks, I still get a type error.
(object[key1] as any)[key2] works but doesn't seem very elegant.

Is there a better way? Would really appreciate an idea.

Below the code + playground.

const POIs = {
  amenity: {
    bar: {
      activity: "night",
      icon: "glass"
    }
  },
  building: {
    supermarket: {
      activiy: "day",
      icon: "warehouse"
    }
  }
}

interface noiseData {
  tags: {
    [T in keyof typeof POIs]: keyof typeof POIs[T]
  }
}


function parseNoiseSources(nss: noiseData[]): void {
  for (const ns of nss) {
    for (const category in POIs) {
      const cat = category as keyof typeof POIs
      const key = ns.tags[cat]
      if (cat in ns) {
        const obj = POIs[cat]
        if (key in obj) {
          const act = POIs[cat][key].activity
          // Below satisfies the compiler but seems redundant
          // const bct = (POIs[cat] as any)[key].activity
        }
      }
    }
  }  
}

The exact error message is this: Element implicitly has an 'any' type because expression of type '"bar" | "supermarket"' can't be used to index type '{ bar: { activity: string; icon: string; }; } | { supermarket: { activiy: string; icon: string; }; }'. Property 'bar' does not exist on type '{ bar: { activity: string; icon: string; }; } | { supermarket: { activiy: string; icon: string; }; }'.

Playground: https://www.typescriptlang.org/play?#code/MYewdgzgLgBACgeQJIRgXhgbwFAxgQwFsBTMASygE8AuLXPGAI3wCdacGH9goyA3CjRgAicgHMAFlGEAaepzKgwtYWIA2+CBGHyYAX3p65eRgFcyagCZkwY9roimADsRaFWAa2JR7nPN14BIWFLfEpZXTxFcBUAd1ZiCRBTCGIdTgM8AwNsGyhXADNuYhgwEDJUgBF8KHw6PFqxCF8GAG0AFRgbGC9KEAKYKhd++GQIAF1aXpGh4hHEFA7xw2wc7ALTMB4ycBgnVlSAOXLUgGVklmBiCAAKSGbSk+Jq2tbxgEpaPnLLepgCkAsGA3JTQUqoEb3d5-PAAoEg8Bg4A1YhiQGULpgUYoaEcPyg2DI2AYImo9EEVDTAazeZjSIwAk9YgYjCQAB0jQgrSJyz8XQGIJqmPBuPpeEZIEYACt0NiuTyxfzgb1hZKpaK+ZxGQFZQt5TVxq1euM2QF+IJFXgAPRWmAAIWIahAsRgEBqFQKZGugwkJVAhCcFlcTFMsFSxEIqBYxEsm1CYCglpgNoZiNgjB4spueu5BopBDAlHeRuZJrNAioisyfmrWUMeFWQA

Thanks a lot for any help!

captain-yossarian

you should add type for your POIs object:

interface DataFrame {
  activity: string;
  icon: string;
}
type Keys = 'amenity' | 'building'
type Data = Record<Keys, Record<string, DataFrame>>


const POIs: Data = {
  amenity: {
    bar: {
      activity: "night",
      icon: "glass"
    }
  },
  building: {
    supermarket: {
      activity: "day",
      icon: "warehouse"
    }
  }
}

interface noiseData {
  tags: {
    [T in keyof typeof POIs]: keyof typeof POIs[T]
  }
}


function parseNoiseSources(nss: noiseData[]): void {
  for (const ns of nss) {
    for (const category in POIs) {
      const cat = category as keyof typeof POIs
      const key = ns.tags[cat]
      if (cat in ns) {
        const obj = POIs[cat]
        if (key in obj) {
          const act = POIs[cat][key].activity // no error
          // Below satisfies the compiler but seems redundant
          // const bct = (POIs[cat] as any)[key].activity
        }
      }
    }
  }
}

bar and supermarket objects should have same types

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Access Object property in Typescript

Typescript access dynamic property with [' '] syntax

Access dynamic property of an interface in Typescript

Access object with dynamic key in Typescript

Typescript access property of an enhanced object

can not access the property object Typescript

Set and access dynamic class property in TypeScript

access property of nested object based on dynamic string

How do you access a dynamic property in an object?

How to filter a list with a property of an object in the second level list using lambda?

Cannot access object property values in Typescript

How to dynamically access object property in TypeScript

Access nth level nested attribute in javascript object using dynamic variable

JavaScript: Access object multi-level property using variable

Typescript - How to access a variable object property from a variable object

Dynamic return type based on object property using string literal in TypeScript

How to tell typescript an object is guaranteed to have a particular (dynamic) property?

How to access property of nested object given dynamic keys?

How to access dynamic named property inside another object in angular?

unable to access dynamic object property and store to state in react

Dataframe access second level of MultiIndex

Dynamic key access in object literal results in widened typescript signature

How to access a property of an object using the bracket notation in TypeScript strict mode

Cannot access property object in Angular.io TypeScript component

Can't access property of object in html or typescript angular

Cannot access nested property from an array of object TypeScript

Velocity Dynamic Property Access

Unable to access dynamic property

When I assign an object to a property of an object, does the property become an object? If so, how do I access the first object via the second one?