Introduction:
I have a multi-dimension object in a TypeScript file, that would look something like this:
const store = {
key_1: "value",
key_2: 123,
key_3: true,
key_4: {
key_4_1: "value",
key_4_2: 123,
key_4_3: false,
key_4_4: [
"value_4_4_1",
"value_4_4_2",
"value_4_4_3",
]
},
key_5: [
"value_5_1",
"value_5_2",
"value_5_3",
],
value_5: {
key_1: "copy-pasted-from-parent-object",
key_2: 123,
key_3: true,
key_4: {
key_4_1: "value",
key_4_2: 123,
key_4_3: false,
key_4_4: [
"value_4_4_1",
"value_4_4_2",
"value_4_4_3",
]
},
key_5: [
"value_5_1",
"value_5_2",
"value_5_3",
]
}
};
Please note that the order, key count, length, value and size of each object and it's child objects/arrays/values can vary from object to object and have no bearing on the final result.
Background:
I want to create an interface or type that enforces the following rules:
- Values in arrays and objects (where the value is not an array or another nested object) must be of type
number,boolean, orstring. - There can never be any
undefined,null, orNaNvalues. - Numbers can never have a negative value (I.E: less than
0). - String values can never be empty.
- The object cannot have more than 4 dimensions (4 nested objects).
- Arrays will never have nested objects or arrays.
- The values of array items will always be of type
string. - All keys for all objects must be of type
string.
Solution 1 and the outcome:
Here is the interface I've tried to use as the type for this object:
interface Store {
[key: string]: string | number | boolean | string[] | Store;
}
However, this does not enforce rules 3, 4, or 5.
Solution 2 (for rules 3 and 4) and the outcome:
To simplify the type checking for rules 3 and 4, I've implemented a loop function that checks the values of strings (boils down to string.length > 0 && number >= 0) and used throw new TypeError(...) to notify me of a mistake.
Question:
How do I change this interface or use a better type to enforce these rules in a more efficient way?