Skapa ett JSON-gränssnitt i TypeScript utan "any."


Jag förstår att detta kan vara omöjligt, med tanke på att returtypen för även den inbyggda JSON.parse-funktionen är any, men jag har funderat på hur man kan skapa ett generiskt JSON-typsnitt i TypeScript. Det finns en lösning på GitHub som kommer väldigt nära:

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])

...men misslyckas med att kompilera i strikt läge:

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

Min förståelse är att eftersom JSONObject och JSONArray har indexvärden, borde unionstypen JSONValue också acceptera en; tydligen håller inte kompilatorn med. Jag är nyfiken för min egen upplysning om det finns något sätt runt detta; med tanke på att GitHub-ärendet var från 2015, kanske TypeScript har förändrats under tiden.

Tack för alla tankar från mer erfarna skript-skrivare!

Svar #1

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

Relaterade artiklar