How to Define an Interface for Objects with Dynamic Keys?

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.

2

6 Answers

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
}
2

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[]> = { ... }
1
{ [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
}
2

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;

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

Instead of using Object as a type use Record

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Sarah Jenkins

Sarah Jenkins

Senior Technology Editor & AI Specialist

Sarah Jenkins is a veteran tech journalist with over 12 years of experience covering artificial intelligence, mobile innovations, and digital ethics. Her insights have appeared in leading technology publications worldwide.

Share this article
Twitter Facebook Pinterest