I have a lot of data I need to sift through on the client side, and to do so I’m looking to use dictionaries for performance reasons. I have the following data structure in JSON (somewhat truncated, as Values
and Styles
can have more data, but this is a shortened version so you can get the picture):
{
"StyleNames": [
"Foo",
"Bar",
"Blah"
],
"Styles": {
"Foo": {
"Dimensions": {
"X": {
"Values": {
"0": 123,
"10": 456,
"50": 789
}
},
"Y": {
"Values": {
"0": 123,
"10": 456,
"50": 789
}
}
}
},
"Bar": {
"Dimensions": {
"X": {
"Values": {
"0": 123,
"10": 456,
"50": 789
}
},
"Y": {
"Values": {
"0": 123,
"10": 456,
"50": 789
}
}
}
}
}
}
I’m having a difficult time getting the TypeScript classes right. The goal is to be able to access a given value via something like this:
import data from './data.json';
let lookupData: ILookupData = data;
let value: number = lookupData.Styles['Foo'].Dimensions['Y'].Values['10']; // Gets a value of 50
The problem is at the let lookupData...
step. I’m getting the following (TL;DR for this block: nothing maps correctly):
“Type ‘{ StyleNames: string[]; Styles: { Foo: { Dimensions: { X: {
Values: { “0”: number; “10”: number; “50”: number; }; }; Y: {
Values: { “0”: number; “10”: number; “50”: number; }; }; }; };
Bar: { Dimensions: { X: { Values: { “0”: number; “10”: number;
“50”: number; }; }; Y: { …; }; }; }; }; }’ is not assignable to
type ‘ILookupData’.Types of property ‘Styles’ are incompatible.
Type ‘{ Foo: { Dimensions: { X: { Values: { “0”: number; “10”:
number; “50”: number; }; }; Y: { Values: { “0”: number; “10”:
number; “50”: number; }; }; }; }; Bar: { Dimensions: { X: { Values:
{ “0”: number; “10”: number; “50”: number; }; }; Y: { Values: {
“0”: number; “10”: number; “50”: number; }; }; }; }; }’ is not
assignable to type ‘IRootStyle’.Property ‘”Foo”‘ is incompatible with index signature.
Type ‘{ Dimensions: { X: { Values: { “0”: number; “10”: number;
“50”: number; }; }; Y: { Values: { “0”: number; “10”: number;
“50”: number; }; }; }; }’ is not assignable to type ‘IStyle’.Types of property ‘Dimensions’ are incompatible.
Type ‘{ X: { Values: { “0”: number; “10”: number; “50”: number;
}; }; Y: { Values: { “0”: number; “10”: number; “50”: number; };
}; }’ is not assignable to type ‘Record<string, IDimension>’.Property ‘”X”‘ is incompatible with index signature.
Type ‘{ Values: { “0”: number; “10”: number; “50”: number; }; }’
is not assignable to type ‘IDimension’.Types of property ‘Values’ are incompatible.
Type ‘{ “0”: number; “10”: number; “50”: number; }’ is not
assignable to type ‘Record<string, IValue>’.Property ‘”0″‘ is incompatible with index signature. Type ‘number’
is not assignable to type ‘IValue’.
I’ve spent about two days trying everything I can find with regards to Record<T,U>
associative arrays/dictionaries, and I’m unable (and possibly inexperienced enough with TypeScript) to figure out how to make an interface model that works here. My current model is this:
export interface IValue {
[key: string] : number;
}
export interface IDimension {
Values: Record<string, IValue>
}
export interface IStyle {
Dimensions: Record<string, IDimension>
}
export interface IRootStyle {
[Name: string]: IStyle;
}
export interface ILookupData {
Styles: IRootStyle;
StyleNames: string[];
}
What am I missing here?