Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a JSON interface in TypeScript without "any."

Tags:

typescript

I gather that this may be impossible, given that the return type of the even the native JSON.parse function is any, but I've been puzzling over how to create a generic JSON type interface in TypeScript. There's a solution on GitHub that comes extremely close:

type JSONValue = boolean | number | string | JSONObject | JSONArray

interface JSONObject {
  [k: string]: JSONValue
}

interface JSONArray extends Array<JSONValue> {}

const json: JSONObject = {}

console.log(json.gray[9])

...but fails to compile in strict mode:

~ ❯❯❯ tsc --strict test.ts
test.ts(11,13): error TS7017: Element implicitly has an 'any' type because type 'JSONValue' has no index signature.

My understanding is that because JSONObject and JSONArray have index values, the union type JSONValue should accept one as well; clearly the compiler disagrees. I'm curious for my own edification whether there's any way around this; given that the GitHub issue was from 2015, maybe TypeScript has changed in the interim.

Thanks for any thoughts from more seasoned script typers!

like image 707
Daniel P. Shannon Avatar asked Oct 12 '25 22:10

Daniel P. Shannon


1 Answers

type JsonObject = { [key: string]: JsonValue };

type JsonValue =
  | null
  | boolean
  | number
  | string
  | JsonValue[]
  | JsonObject;

const stringify = (subject: JsonObject) => {};

stringify({
  foo: 'bar',
});

stringify({
  // @ts-expect-error
  foo: () => {}
});

https://www.typescriptlang.org/play?ssl=20&ssc=4&pln=1&pc=1#code/C4TwDgpgBAUgzgewHYHkBGArCBjYUC8UA3lANoDWEIAXFHMAE4CWSA5gLq3zIBqAhgBsArtAC+AbgCwAKBmhIsREn7Do+GVCgAfKEiECBG7VDQIEAiHyRGdegLZoIDG3UYtWL7ssEjS7T0roWLhSstLYyPSuzGxMAGYgBFAAFHBCmDjAXIEZuACUBAB8xBIyMvQxrPEgyURGcWa0AORofAxNADQyonmh5W6xCbVGAPQjUAACwHAAtBAAHpC4cwwMCM7Smg0ItMkF+MVEot29QA

like image 193
Gajus Avatar answered Oct 16 '25 05:10

Gajus