type NodeValueType = { Number: "number", String: "string", Map: "map", Expression: "expression" }; type ExpressionType = { Count: "count", Filter: "filter", }; type Filter = { value: number, predicate: "greatThat" | "greatThatEqual" | "lessThat" | "lessThatEqual" | "equal" } | { value: string, predicate: "include" | "equal" } type CountWithExpression = { type: ExpressionType["Count"], expression: BaseNode["uuid"], }; type CountWithSet = { type: ExpressionType["Count"], set: string, }; type FilterWithExpression = { type: ExpressionType["Filter"], expression: BaseNode["uuid"], filter: Filter, }; type FilterWithSet = { type: ExpressionType["Filter"], set: string, filter: Filter, }; type Expression = CountWithExpression | CountWithSet | FilterWithExpression | FilterWithSet; type NumberNode = BaseNode & { valueType: NodeValueType["Number"]; value: number; }; type StringNode = BaseNode & { valueType: NodeValueType["String"]; value: string; }; type MapString = BaseNode & { valueType: NodeValueType["Map"]; value: { [key: string]: Node["uuid"]; }; }; type ExpressionNode = BaseNode & { valueType: NodeValueType["Expression"]; value: Expression; id: string; }; type BaseNode = { uuid: string; set: string; }; type PrimitiveValue = string | number; type MapValue = { [key: string]: PrimitiveValue | MapValue; } type ExpressionResult = PrimitiveValue | MapValue | Array | null; type AddNodeParams = Omit; type AnyNode = NumberNode | StringNode | MapNode | ExpressionNode;