I am reading a JSON file with the following structure:
[
{
"key1" : {
"A": 1,
"B": 2,
...
}
},
{
"key1" : {
"A": 2,
"B": 3,
...
}
},
{
"key2" : {
"A": 3,
...
}
},
{
"key3" : {
"A": 4,
...
}
},
...
]
Some facts about the file:
- I know that it will contain an array of various length,
- the array will consist of specific object, which might or might not be always present but if they are, I know the structure (usually a nested object),
- moreover, some 'objects' might have the same structure (for example
key1
in the above example).
I want to define interfaces for the JSON array, so I define it like this:
export type Root = JsonObject[]
export interface JsonObject {
[key: string]: Key1 | Key2 | Key3
}
export interface Key1 {
A: number;
B: number;
...
}
export interface Key2 {
A: number;
...
}
export interface Key3 {
A: number;
...
}
However when I try to loop over the array and do some action based on which object I currently loop over:
for (const member of parsedJsonFile) {
// I check whether the first key is equal to certain value
// and I execute certain logic based on that
if (Object.keys(member)[0] === 'key1') {
let memberOfTypeKeyOne: Key1 = member.key1;
console.log(memberOfTypeKeyOne.B)
}
}
I get the following error:
Type 'Key1 | Key2 | Key3' is not assignable to type 'Key1'.
Type ... is missing the following properties from type ...: ...
I would like to force the variable memberOfTypeKeyOne
to be of type Key1, because I know it will be, to get type hinting, type checking etc..
How can I tell TypeScript compiler, that I know this variable will be of certain type from union?
Is this even possible, or am I going completely in the wrong direction and I should rethink the whole logic?
CodePudding user response:
for (const member of parsedJsonFile) {
if (typeof member.key1 !== 'undefined' && Object.keys(member)[0] === 'key1') {
let memberOfTypeKeyOne: Key1 = member.key1;
console.log(memberOfTypeKeyOne.B)
}
}
CodePudding user response:
At the end of the day I just used type assertion, this should have occurred to me sooner.
For anyone else wondering, this is how it looks like:
for (const member of parsedJsonFile) {
// I check whether the first key is equal to certain value
// and I execute certain logic based on that
if (Object.keys(member)[0] === 'key1') {
let memberOfTypeKeyOne: Key1 = member.key1 as Key1; //