Consider the file data.json:
{
"au": {
"name": "Australia",
"market_id": "111172",
"language_code": "en_AU"
},
"br": {
"name": "Brazil",
"market_id": "526970",
"language_code": "pt_BR"
},
"ch": {
"name": "China",
"market_id": "3240",
"language_code": "zh_CN"
},
"de": {
"name": "Germany",
"market_id": "4",
"language_code": "de_DE"
}
...many more
}
In Typescript, we can import that file as a json module ("resolveJsonModule": true in tsconfig.json):
import lookup from './data.json'
The imported module has type information:
type LookupType = typeof lookup
LookupType = {
au: {
name: string;
market_id: string;
language_code: string;
};
br: {
name: string;
market_id: string;
language_code: string;
};
ch: {
name: string;
market_id: string;
language_code: string;
};
de: {
name: string;
market_id: string;
language_code: string;
};
...
}
With that type information in place we can do something like this:
type CountryCodes = keyof LookupType
CountryCodes = "au" | "br" | "ch" | "de" | ...
What I would like to do however, is to extract a type that represents all possible values for a given nested field in the json.
For example:
type MarketIds = LookupType[keyof LookupType]['market_id']
MarketIds = string // I'd like "111172" | "526970" | "3240" | "4" ...
The issue being that Typescript sees LookupType[keyof LookupType] as a type erased union:
LookupType[keyof LookupType] = {
name: string;
market_id: string;
language_code: string;
} | {
name: string;
market_id: string;
language_code: string;
} | {
name: string;
market_id: string;
language_code: string;
} | {
name: string;
market_id: string;
language_code: string;
} ...
I understand this might simply be a hard limitation of Typescript. - Understandably, given that deeply nested typed json data would blow up the compiler, I guess.
However, since I've not found any definite information in the docs about json modules only supporting one level of type information, I have hope that there might be some way to achieve the goal outlined above.
constassertion for json module imports, which is a requested feature microsoft/TypeScript#32063 but has not been implemented. I don't know of any way to deal with this other than the clunky build step workarounds in that issue.