title: Typescript Generic 'Once' function
body: <p>I am using a function from FP called Once(). As I am using TS I need to type it but can't work it out for this implementation. Here is my effort so far;</p>
  
  <pre><code>const once = &lt;T, U&gt;(fn: (arg: T) =&gt; U): () =&gt; U | undefined =&gt; {
  let done = false;
  return function(this: (args: T) =&gt; U) {
      return done ? void 0 : ((done = true), fn.apply(this, arguments));
  };
  </code></pre>
  
  <p>}</p>
  
  <p>I am using this for a method in a class:</p>
  
  <pre><code>class CSVOutput extends LogOutput {
  private print_headers: (logStat: IStats) =&gt; void;
  constructor() {
      super();
      this.print_headers = once((logStat: IStats) =&gt; {
          console.log(Object.keys(logStat).join(','));
      });
  }
  public print(logStat: IStats) {
      this.print_headers(logStat);
      console.log(Object.values(logStat).join(','));
  }
  </code></pre>
  
  <p>}</p>
  
  <p>my <code>tsconfig.json</code> looks like </p>
  
  <pre><code>{
  "compilerOptions": {
      "esModuleInterop": true,
      "lib": ["es6", "es7", "es2017"],
      "module": "commonjs",
      "sourceMap": true,
      "target": "es6",
      "types": ["node", "mocha"],
      "allowJs": true,
      "outDir": "./dist",
      "preserveSymlinks": true,
      "strict": true,
      "baseUrl": "."
  }
  </code></pre>
  
  <p>}</p>
  
  <p>I get the TS warning <code>Argument of type 'IArguments' is not assignable to parameter of type '[T]'.</code></p>
  
  <p>How do I correctly write this function in typescript?</p>