interface DeterminedExtraSerializer { determine: (value: any) => boolean; } export interface ExtraSerializer extends DeterminedExtraSerializer { serialize: (value: T) => S; deserialize: (serializedValue: S) => T; } export interface ConstantExtraSerializer extends DeterminedExtraSerializer { deserialize: () => T; } export interface RecursiveExtraSerializer extends ExtraSerializer { initialize: (created: T, serializedValue: S) => void; } export type UnifiedExtraSerializer = | ConstantExtraSerializer | ExtraSerializer | RecursiveExtraSerializer; export function isExtraSerializer(serializer: UnifiedExtraSerializer): serializer is ExtraSerializer { return !isConstantExtraSerializer(serializer) && !isRecursiveExtraSerializer(serializer); } export function isConstantExtraSerializer(serializer: UnifiedExtraSerializer): serializer is ConstantExtraSerializer { return !(serializer as ExtraSerializer).serialize; } export function isRecursiveExtraSerializer(serializer: UnifiedExtraSerializer): serializer is RecursiveExtraSerializer { return !!(serializer as RecursiveExtraSerializer).initialize; } export type ExtraSerializerRef = {}; export type ExtraSerializerId = string; export type ExtraSerializersPreset = { [Id in ExtraSerializerId]: UnifiedExtraSerializer; };