Skip to content

Instantly share code, notes, and snippets.

@graffhyrum
Created September 28, 2023 21:49
Show Gist options
  • Select an option

  • Save graffhyrum/4d17f91a6aa130270981f47d7f574685 to your computer and use it in GitHub Desktop.

Select an option

Save graffhyrum/4d17f91a6aa130270981f47d7f574685 to your computer and use it in GitHub Desktop.
Typescript JSON type
/**
* JSONValue is a type alias for narrowing or validating JSON.
* Requires an indirection via the DelayedJsonValue interface
* to establish a 'root' type, Record<string,JSONValue> causes
* recursion errors.
*/
export type JSONValue =
| JsonPrimitive
| JsonArray
| JsonObject
| DelayedJsonValue;
type JsonPrimitive = string | number | boolean | null;
type JsonArray = Array<JSONValue>;
type JsonObject = {[key: string]: JSONValue};
interface DelayedJsonValue {
value: JSONValue;
}
// comprehensive JSON example
const myJson: JSONValue = {
string: 'Hello, world!',
number: 42,
boolean: true,
null: null,
array: [
'foo',
123,
false,
null,
{
nestedString: 'bar',
nestedNumber: 456,
nestedBoolean: true,
nestedNull: null,
nestedArray: [],
},
],
object: {
nestedString: 'baz',
nestedNumber: 789,
nestedBoolean: false,
nestedNull: null,
nestedArray: [
'qux',
987,
true,
null,
{
deeplyNestedString: 'quux',
deeplyNestedNumber: 654,
deeplyNestedBoolean: false,
deeplyNestedNull: null,
deeplyNestedArray: [],
},
],
},
};
isJsonValue(myJson); // true
export function isJsonValue(value: unknown): value is JSONValue {
if (typeof value === 'string') {
return true;
}
if (typeof value === 'number') {
return true;
}
if (typeof value === 'boolean') {
return true;
}
if (value === null) {
return true;
}
if (Array.isArray(value)) {
return value.every(isJsonValue);
}
if (typeof value === 'object') {
return Object.values(value).every(isJsonValue);
}
return false;
}
export function assertIsJsonValue(value: unknown): asserts value is JSONValue {
if (!isJsonValue(value)) {
throw new Error('Value not valid JSON.');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment