I have two types of filter functions: NodeFilter and EdgeFilter
e.g. type NodeFilter = (node: Node) => boolean
I'd like to write a function Graph::filter(filters: NodeFilter | EdgeFilter): Graph which applies the filters to nodes and edges of the Graph, to create a new Graph.
So in filter I need to do
if (filter is type NodeFilter) nodes = nodes.filter(filter)
else if (filter is type EdgeFilter) edges = edges.filter(filter)
I've seen recommendations of adding a "type" property to instances. e.g.
function myNodeFilter(node: Node): boolean { // do the filtering and return boolean }
myNodeFilter.type = "NodeFilter";
Is there a better way? Maybe defining a callable class instance?
You can use descriminated unions for this with a sprinkle of call signature.
/**
* Kindly ignore the naming,
* it was conflicting with the DOM Node and NodeFilter function (since I tested this in typescript playground)
**/
type NodeF = {};
type Edge = {}
type NodeFilterr = {
(node: NodeF): boolean,
type: "NodeFilter"
}
type EdgeFilter = {
(edge: Edge): boolean,
type: "EdgeFilter"
}
function f(filter: NodeFilterr | EdgeFilter ) {
if ( filter.type === "NodeFilter" ) {
// do stuff
}
if ( filter.type === "EdgeFilter" ) {
// do stuff
}
}