Update: 7/26/2021
I revisited the discussion noted in the original answer, and there is now an update with an improved implementation.
type JSONValue =
| string
| number
| boolean
| null
| JSONValue[]
| {[key: string]: JSONValue}
interface JSONObject {
[k: string]: JSONValue
}
interface JSONArray extends Array<JSONValue> {}
This has been working very well for me.
Discussion reference: https://github.com/microsoft/TypeScript/issues/1897#issuecomment-822032151
Original answer: Sep 29 '20
I realize this is an old question, but I just found a solution that worked very well for me. Declare the following
type JsonPrimitive = string | number | boolean | null
interface JsonMap extends Record<string, JsonPrimitive | JsonArray | JsonMap> {}
interface JsonArray extends Array<JsonPrimitive | JsonArray | JsonMap> {}
type Json = JsonPrimitive | JsonMap | JsonArray
then any of the following (including the OP's version slightly modified for syntax errors) will work
let a: Json = {};
a[1] = 5;
a["abc"] = "abc";
a = {
a: {
a: 2,
},
b: [1, 2, 3],
c: true,
};
a = [
{
"id": 1,
"title": "something",
"node": [
{
"id": 1,
"title": "something",
"node": [],
},
],
},
{
"id": 2,
"title": "something",
"node": [
{
"id": 1,
"title": "something",
"node": [],
},
],
},
];
This answer should be credited to Andrew Kaiser who made the suggestion on the discussion about making Json a basic type in Typescript: https://github.com/microsoft/TypeScript/issues/1897#issuecomment-648484759