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.
ObjectX
have a type or are they just any
?
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
}
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[]> = { ... }
export type MyType = Record<string, object[]>;
{ [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
}
string
. You may use any
or unknown
if they may have any value. In the export type obj<T = unknown> = Record<string, T>
example, it is a generic type. T here will have by default the unknown type, but as the last example shows, you may specifically cast it with obj<number>
. T will be a number. Feel free to ask for more explanations, I know TS can be somewhat confusing at first. But it is really awesome when you understand its power! :)
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>[]
}
Success story sharing