Description
Hi,
JSON is an important data exchange format. At present there is no explicit way to annotate an object as pure JSON. We were expecting union types to solve this problem via the following:
interface Json {
[x: string]: string|number|boolean|Date|Json|JsonArray;
}
interface JsonArray extends Array<string|number|boolean|Date|Json|JsonArray> { }
There are currently a number of problems with this.
-
Contextual typing is absent in parenthetic expression Consider contextually typing parenthesized expressions #920
interface Id extends Json { id: number; } var z = (): Id => ({id: 'foo'}); // Error: Missing index signature
-
Contextual typing does not flow from base to subclasses Consider contextually typing class member functions by their base class/interface members #1373
class Bass {
f(): Id{ return undefined;}
}
// Error: missing index signature
class Foo extends Bass {
f() { return { id: 10 }}
}
- Object literals require explicit index signatures Recursive type with index signature issues spurious error #1889:
interface Foo extends Json {
foo: { val: string }; // Error: Not assignable
}
-
Other problems:
// Error: Missing index signature var result: Id[] = 'a|b'.split('|').map(item => { return { id: 0 }; });
The first two problems look likely to be resolved, but not the last two.
This motivates the introduction of a natively supported json
type that conforms to the JSON spec.
It should be possible to derive a custom JSON object from the json
type with non of the problems above. Furthermore, since JSON is a data exchange format it should be possible to mark fields as nullable on types deriving from json
(which would trigger a type guard).
I am of course aware that this is all rather vague!