or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

dom-enhancements.mdes2015-features.mdes5-core.mdindex.mdjson-types.mdtyped-arrays.md
tile.json

json-types.mddocs/

JSON Types

Comprehensive type definitions for JSON data structures, providing type-safe alternatives to any for JSON operations. This is one of the key improvements in better-typescript-lib.

Capabilities

JSON Object

The global JSON object with improved type safety for parsing and stringifying operations.

interface JSON {
  /**
   * Converts a JSON string into an object.
   * Returns JSONValue instead of any for better type safety.
   */
  parse(text: string): JSONValue;

  /**
   * Converts a JSON string into an object with a reviver function.
   * Generic version allowing custom return types.
   */
  parse<A = unknown>(
    text: string,
    reviver: <K extends string>(
      this: JSONHolder<K, A>,
      key: K,
      value: JSONValueF<A>,
    ) => A,
  ): A;

  /**
   * Converts a JavaScript value to a JSON string.
   */
  stringify<A>(
    value: A,
    replacer?: (string | number)[] | null | undefined,
    space?: string | number | null | undefined,
  ): StringifyResult<ToJSON<A>>;

  /**
   * Converts a JavaScript value to a JSON string with replacer function.
   */
  stringify<A>(
    value: A,
    replacer:
      | ((
          this: JSONComposite<A>,
          key: string,
          value: ToJSON<A>,
        ) => JSONValueF<A>)
      | null
      | undefined,
    space?: string | number | null | undefined,
  ): string;
}

Usage Examples:

// Basic JSON parsing - now returns JSONValue instead of any
const data = JSON.parse('{"name": "Alice", "age": 30, "active": true}');
// data is JSONValue, requiring type guards for safe access

// Type-safe property access
if (typeof data === 'object' && data !== null && !Array.isArray(data)) {
  const name = data.name; // Type: JSONValue | undefined
  if (typeof name === 'string') {
    console.log(name.toUpperCase()); // Safe string operation
  }
}

// Using reviver function with custom types
type UserData = {
  name: string;
  birthDate: Date;
};

const userData = JSON.parse<UserData>('{"name": "Bob", "birthDate": "2023-01-01"}', 
  (key, value) => {
    if (key === 'birthDate' && typeof value === 'string') {
      return new Date(value);
    }
    return value;
  }
);

Core JSON Types

Fundamental type definitions for representing JSON data structures.

/**
 * Primitive values that can be represented in JSON
 */
type JSONPrimitive = string | number | boolean | null;

/**
 * Any value that can be represented in JSON
 */
type JSONValue = JSONPrimitive | JSONObject | JSONValue[];

/**
 * A JSON object (key-value pairs)
 */
type JSONObject = { [key: string]: JSONValue };

/**
 * Generic JSON composite type allowing additional value types
 */
type JSONComposite<A> = { [key: string]: JSONValueF<A> } | JSONValueF<A>[];

/**
 * Generic JSON value type with parameterized additional types
 */
type JSONValueF<A> = JSONPrimitive | JSONComposite<A>;

/**
 * Record type for JSON data with specific key and value constraints
 */
type JSONHolder<K extends string, A> = Record<K, JSONValueF<A>>;

/**
 * Utility type for JSON stringification
 */
type ToJSON<A> = A extends { toJSON(...args: any): infer T } ? T : A;

/**
 * Helper types for stringify result handling
 */
type SomeFunction = (...args: any) => any;
type SomeConstructor = new (...args: any) => any;
type UndefinedDomain = symbol | SomeFunction | SomeConstructor | undefined;
type SomeExtends<A, B> = A extends B ? undefined : never;
type StringifyResultT<A> = A extends UndefinedDomain ? undefined : string;
type StringifyResult<A> = StringifyResultT<A> | SomeExtends<UndefinedDomain, A>;

Usage Examples:

// Working with JSONValue
function processUserData(data: JSONValue): void {
  if (typeof data === 'object' && data !== null && !Array.isArray(data)) {
    // data is JSONObject
    const name = data.name;
    if (typeof name === 'string') {
      console.log(`Processing user: ${name}`);
    }
  }
}

// Creating type-safe JSON structures
const userProfile: JSONObject = {
  id: 123,
  name: "Alice",
  email: "alice@example.com",
  preferences: {
    theme: "dark",
    notifications: true
  },
  tags: ["developer", "typescript"]
};

// Working with JSONValueF for extended types
type JSONWithDate = JSONValueF<Date>;

function handleExtendedJSON(data: JSONWithDate): void {
  if (data instanceof Date) {
    console.log(`Date: ${data.toISOString()}`);
  } else if (typeof data === 'object' && data !== null) {
    // Handle JSON object or array
  }
}

Type Guards

Utility functions for safely working with JSON types.

// Example type guards you can implement
function isJSONObject(value: JSONValue): value is JSONObject {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

function isJSONArray(value: JSONValue): value is JSONValue[] {
  return Array.isArray(value);
}

function isJSONPrimitive(value: JSONValue): value is JSONPrimitive {
  return value === null || 
         typeof value === 'string' || 
         typeof value === 'number' || 
         typeof value === 'boolean';
}

// Usage with type guards
const jsonData = JSON.parse(jsonString);

if (isJSONObject(jsonData)) {
  // jsonData is now typed as JSONObject
  const keys = Object.keys(jsonData);
  
  for (const key of keys) {
    const value = jsonData[key];
    // value is JSONValue
  }
}

Advanced Patterns

Working with complex JSON structures and generic types.

// Custom JSON value types for specific domains
type APIResponse = JSONValueF<{
  timestamp: Date;
  version: string;
}>;

// Working with nested JSON structures
interface UserJSON extends JSONObject {
  id: number;
  profile: {
    name: string;
    email: string;
    settings: JSONObject;
  };
  history: JSONValue[];
}

// Type-safe JSON transformation
function transformJSONUser(data: JSONValue): UserJSON | null {
  if (!isJSONObject(data)) return null;
  
  const id = data.id;
  const profile = data.profile;
  
  if (typeof id !== 'number' || !isJSONObject(profile)) {
    return null;
  }
  
  return data as UserJSON;
}