How to define an interface for objects with dynamic keys?

Typescript

Typescript Problem Overview


I have an Object like this that is created by underscore's _.groupBy() method.

myObject = {
  "key" : [{Object},{Object2},{Object3}],
  "key2" : [{Object4},{Object5},{Object6}],
  ...
}

How would I define that as an Interface with TypeScript? i don't want to simply define it as myObject:Object = { ... but rather have an own type for it.

Typescript Solutions


Solution 1 - Typescript

Your object looks like a dictionary of Object arrays

interface Dic {
    [key: string]: Object[]
}

The typescript literature often refers to this pattern as "the description of an indexable object" with a general form

interface Dic {
    [key: string|number]: object_type
}

or

type Dic = {
    [key: string|number]: object_type
}

Solution 2 - Typescript

There's now a dedicated Record type in TypeScript:

const myObject: Record<string, object[]> = { ... }

Also, consider typing the keys whenever possible:

type MyKey = 'key1' | 'key2' | ...

const myObject: Record<MyKey, object[]> = { ... }

Solution 3 - Typescript

{ [x: string]: T }

and

Record<string, T>

usually will serve for all your objectives. However, I got to a strange point where after some type operations the first option was returning to me both [x: string] and [x: number], and I wasn't being able to use the Record, as it was a recursive type operation and Typescript was throwing an error saying my recursive type wasn't generic.

So, studying the really small Record code, I came to this solution that solved my complex problem:

{ [P in string]: T }

Edit: I also usually have this in every Typescript code I write, in a utils.ts file:

export type obj<T = unknown> = Record<string, T>

Faster and cleaner than using the Record all the time.

E.g.:

type MyObjectType = {
  propA: obj; // An object with unknown props
  propB: obj<number>; // An object with number props
}

Solution 4 - Typescript

don't know about interface, for dynamic objects we can go something like this:

let memoTable: { [k: number]: number } = {};
memoTable[1]=5;
memoTable[2]=7;

Solution 5 - Typescript

I would suggest a solution with Map, maybe for someone it will be useful:

type TKey = 'key1' | 'key2' | 'key3';
type TValue = object[];

type TMapper = Map<TKey, TValue>; // But also you can use Record instead of Map

Solution 6 - Typescript

Instead of using Object as a type use Record

interface myObjInterface {
  [key: string]: Record<string, any>[]
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionManuel SchillerView Question on Stackoverflow
Solution 1 - TypescriptBruno GriederView Answer on Stackoverflow
Solution 2 - TypescriptMikael CouzicView Answer on Stackoverflow
Solution 3 - TypescriptHenrique BrunoView Answer on Stackoverflow
Solution 4 - TypescriptAsutoshView Answer on Stackoverflow
Solution 5 - TypescriptzemilView Answer on Stackoverflow
Solution 6 - TypescriptKritiView Answer on Stackoverflow