在TypeScript中实现D3"可重用图表"模式

Lea*_*cim 15 javascript d3.js typescript

下面第2节中的代码(这里的工作示例)基于第1节中的代码,但更改为使用箭头函数,它基于Mike Bostock在Toward Resusable Charts中的模式,即返回一个具有其他函数的函数.

如果我尝试在typescript(这里演示)中运行第1或第2部分中的代码,它会说出方法addToChart并且stop不存在类型(selection: any) => () => void.

我怎样才能得到打字稿识别功能性(addToChartstop在这种情况下)添加到返回的功能?

第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"
Run Code Online (Sandbox Code Playgroud)

第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"
Run Code Online (Sandbox Code Playgroud)

alt*_*lus 7

您可以定义混合类型,即描述函数签名及其属性的接口.鉴于您的代码,它可能是这样的:

interface IChart {
    (selection: any): any;
    // Use overloading for D3 getter/setter pattern
    addToChart(): string;               // Getter
    addToChart(value: string): IChart;  // Setter
}
Run Code Online (Sandbox Code Playgroud)

既然你应该any像瘟疫那样避免这可能需要进一步改进,但它应该足以让你开始.此外,为了允许D3-ish getter/setter模式,您可以在接口声明中重载addToChart函数.

将此接口集成为可重用代码模式中的类型现在变得非常简单:

const mychart = (): IChart => {

  // Private value exposed via closure
  let value: string|undefined;

  const chart = <IChart>((selection) => {
    // Private logic
  });

  // Public interface
  // Implementing a  D3-style getter/setter.
  chart.addToChart = function(val?: string): any {
    return arguments.length ? (value = val, chart) : value;
  };

  return chart;
} 

const chart = mychart();

console.log(chart.addToChart())   // --> undefined       
chart.addToChart("Add");          // Sets private value to "Add".
console.log(chart.addToChart())   // --> "Add"       
Run Code Online (Sandbox Code Playgroud)

看看可执行的游乐场演示.


Jos*_*ora 3

我想知道你是否可以使用接口/类:

interface IChart {
    constructor: Function;
    addToChart?: (number) => Chart;
    stop: () => boolean;
}

class Chart implements IChart {

    private _stop = false;
    constructor( selection ) {
        // content of tick funciton here
    }

    public addToChart = function (n: number) {
        return this;
    }
    public stop = function () {
        return this._stop = true;
    }

}

let mychart = function () {
    let stop = false;
    let chartNew: Chart = new Chart(1);
    return chartNew;
}; 
Run Code Online (Sandbox Code Playgroud)