import { Refinement } from "@siteimprove/alfa-refinement" ; import { JSON } from "./json" ; const { keys } = Object ; const { isArray } = Array ; const { isFunction , isObject , isString , isNumber , isBoolean , isNull } = Refinement ; public export interface Serializable < T extends JSON = JSON > { toJSON ( ) : T ; } public export namespace Serializable { export type ToJSON < T > = T extends Serializable < infer U > ? U : T extends JSON ? T : JSON ; export function isSerializable < T extends JSON > ( value ) { return isObject ( value ) && isFunction ( value . toJSON ) ; } export function toJSON < T extends JSON > ( value ) ; export function toJSON < T > ( value ) ; export function toJSON ( value ) { if ( isSerializable ( value ) ) { return value . toJSON ( ) ; } if ( isString ( value ) || isNumber ( value ) || isBoolean ( value ) || isNull ( value ) ) { return value ; } if ( isArray ( value ) ) { return value . map ( toJSON ) ; } if ( isObject ( value ) ) { const json = { } ; for ( const key of keys ( value ) ) { if ( value [ key ] !== undefined ) { json [ key ] = toJSON ( value [ key ] ) ; } } return json ; } return null ; } }