Implementing the D3 "reusable chart" pattern in TypeScript

Viewed 587

The code in section 2 below (working example here) is based on the code in section 1 but changed to use arrow functions, and it is based on Mike Bostock's pattern in Toward Resusable Charts, namely returning a function that has other functions on it.

If I try to run either the code in section 1 or 2 in typescript (demo here) it says the methods addToChart and stop do not exist on type (selection: any) => () => void.

How can I get typescript to recognize the functions properties (addToChart and stop in this case) added to the returned function?

section 1

const mychart = function (){
  let stop = false;
  const chart = function(selection){
    function tick(){
      console.log("tick");
    }
    return tick;
  };

  // Adding a function to the returned 
  // function as in Bostock's reusable chart pattern
  chart.addToChart = function(value){ 
    console.log("addToChart");
    return chart;
  };

  chart.stop = function(){
    return stop = true;
  }

  return chart;
}

const a = mychart();
const tick = a();
tick(); //logs tick
a.addToChart(); //logs "addToChart"

section 2

const mychart = () => {
  let stop = false;

  const chart = (selection) => {
    function tick(){
      console.log("tick");
    }
    return tick;
  };

  chart.addToChart = (value) => {
    console.log("addToChart");
    return chart;
  };

  chart.stop = () => {
    return stop = true;
  }

  return chart;
} 

const a = mychart();
const tick = a();
tick(); //logs tick
a.addToChart(); //logs "addToChart"
3 Answers
Related