Jsonify: IsAny<T> extends true
    ? any
    : T extends PositiveInfinity
    | NegativeInfinity
        ? null
        : T extends JsonPrimitive
            ? T
            : T extends Number
                ? number
                : T extends String
                    ? string
                    : T extends Boolean
                        ? boolean
                        : T extends Map<any, any>
                        | Set<any>
                            ? EmptyObject
                            : T extends TypedArray
                                ? Record<string, number>
                                : T extends NotJsonable
                                    ? never
                                    : T extends { toJSON(): ... }
                                        ? (...) extends (...) ? (...) : (...)
                                        : (...) extends (...) ? (...) : (...)

Transform a type to one that is assignable to the JsonValue type.

This includes:

  1. Transforming JSON interface to a type that is assignable to JsonValue.
  2. Transforming non-JSON value that is jsonable to a type that is assignable to JsonValue, where jsonable means the non-JSON value implements the .toJSON() method that returns a value that is assignable to JsonValue.

Type Parameters

  • T

An interface cannot be structurally compared to JsonValue because an interface can be re-opened to add properties that may not be satisfy JsonValue.

import type {Jsonify, JsonValue} from 'type-fest';

interface Geometry {
type: 'Point' | 'Polygon';
coordinates: [number, number];
}

const point: Geometry = {
type: 'Point',
coordinates: [1, 1]
};

const problemFn = (data: JsonValue) => {
// Does something with data
};

problemFn(point); // Error: type Geometry is not assignable to parameter of type JsonValue because it is an interface

const fixedFn = <T>(data: Jsonify<T>) => {
// Does something with data
};

fixedFn(point); // Good: point is assignable. Jsonify<T> transforms Geometry into value assignable to JsonValue
fixedFn(new Date()); // Error: As expected, Date is not assignable. Jsonify<T> cannot transforms Date into value assignable to JsonValue

Non-JSON values such as Date implement .toJSON(), so they can be transformed to a value assignable to JsonValue:

import type {Jsonify} from 'type-fest';

const time = {
timeValue: new Date()
};

// `Jsonify<typeof time>` is equivalent to `{timeValue: string}`
const timeJson = JSON.parse(JSON.stringify(time)) as Jsonify<typeof time>;