Skip to main content

Jsonable TypeAlias

Used to constrain a type T to types that are serializable as JSON. Produces a compile-time error if T contains non-Jsonable members.

This API is provided for existing users, but is not recommended for new users.

To use, import via @fluidframework/datastore-definitions/legacy.

For more information about our API support guarantees, see here.

Signature

export type Jsonable<T, TReplaced = never> = boolean extends (T extends never ? true : false) ? JsonableTypeWith<TReplaced> : unknown extends T ? JsonableTypeWith<TReplaced> : T extends undefined | null | boolean | number | string | TReplaced ? T : Extract<T, Function> extends never ? T extends object ? T extends (infer U)[] ? Jsonable<U, TReplaced>[] : {
[K in keyof T]: Extract<K, symbol> extends never ? Jsonable<T[K], TReplaced> : never;
} : never : never;

Type Parameters

Parameter Default Description
T
TReplaced never

Remarks

Note that this does NOT prevent using of values with non-json compatible data, it only prevents using values with types that include non-json compatible data. This means that one can, for example, pass in a value typed with json compatible interface into this function, that could actually be a class with lots on non-json compatible fields and methods.

Important: T extends Jsonable<T> is incorrect (does not even compile).

The optional 'TReplaced' parameter may be used to permit additional leaf types to support situations where a replacer is used to handle special values (e.g., Jsonable<{ x: IFluidHandle }, IFluidHandle>).

Note that Jsonable<T> does not protect against the following pitfalls when serializing with JSON.stringify():

  • undefined properties on objects are omitted (i.e., properties become undefined instead of equal to undefined).

  • When undefined appears as the root object or as an array element it is coerced to null.

  • Non-finite numbers (NaN, +/-Infinity) are also coerced to null.

  • prototypes and non-enumerable properties are lost.

  • ArrayLike types that are not arrays and are serialized as { length: number }.

Also, Jsonable<T> does not prevent the construction of circular references.

Using Jsonable<unknown> or Jsonable<any> is a type alias for JsonableTypeWith<never> and should not be used if precise type safety is desired.

Example

Typical usage

function foo<T>(value: Jsonable<T>) { ... }