TypeScriptでオプション引数を指定しつつ、Function#lengthに正規の値を入れる方法


JavaScript(ECMAScript)において、`Function.prototype.length` は必須パラメータの数を返します。

  * [Function.length - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/length)

ECMAScriptでオプション引数を指定するには、`arguments` もしくは「rest parameter」を使用する方法があります。  
`arguments` は class 構文等の一部構文で使用できない為、「rest parameter」を使用するのが概ね現実解となります。

[code]

    'use strict';
    function foo (...args) {
      if (args.length && typeof args[0] !== 'string') throw new TypeError(args[0] + ' is not a string');
    }
    
    function bar () {
      if (arguments.length && typeof arguments[0] !== 'string') throw new TypeError(arguments[0] + ' is not a string');
    }
    
    console.log(foo.length);  // 0
    console.log(bar.length);  // 0
    foo();
    bar();
[/code]

一方、TypeScriptではオプション引数を指定する方法に `?` がありますが、この構文を使用した場合、
**Function.prototype.length が不正値になります** 。

[code]

    // TypeScript
    function foo (string?:string) {}
    console.log(foo.length); // 1
    foo();
    
[/code]

「rest parameter」でany型を指定しつつ、各々の引数を型付き変数に代入すれば、ECMAScriptと同じ実装になりますが、
**変数定義が必須** になってしまいます。。

[code]

    // TypeScript
    function foo (...args:any) {
      const string: string = args[0];
    }
    console.log(foo.length); // 0
    foo();
    
[/code]

TypeScriptで次の条件を満たすことは可能でしょうか。

  * `Function.prototype.length` が必須パラメータの数を返す
  * 仮引数で「型指定」かつ「オプション引数指定」を行う




トランスパイル結果から想像するに、 TypeScript の `function foo(text?: string) {}` は JavaScriptの
`function foo(text) {}` 相当になるようにデザインされているので無理ではないでしょうか。  
(引数が存在しないわけではなく、呼び出し時に省略した場合に`undefined`が代入される)

代替策としては、[仕様](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/length#%E8%A7%A3%E8%AA%AC)の

> 既定値を持つ引数が最初に登場する前までしか含みません

を利用する方法が考えられます。  
(`"target": "ES6"` (以降)の設定が必要)

[code]

    // TypeScript
    function foo(text: string | undefined = undefined) {}
    console.log(foo.length); // 0
    foo();
    
[/code]

([playground](https://www.typescriptlang.org/play?target=2#code/PTAEBUE8AcFMGUDGAnAltALgKAGYFcA7RDVAewNB1NIAoNYAPDALlAGcM0CBzUAH1CEAJrByoCsIaAC8ggiLEShASlABvAL5ZE5NqQA2sAHT7S3GlVInYPDAAtlAblAhQABlzUaTrEA))

