.NETのTypeScript宣言ファイルの生成

  • 概要

    hmV8用のマクロは、ECMAScript6で記述しても良いですが、
    TypeScriptで記述する、という選択肢が最有力となります。

    TypeScriptで記述することで、ECMAScript部分の型の間違いが事前に解消されるだけでなく、
    hmV8が利用可能な「.NET Frameworkライブラリ」の入力補完も手堅い形で可能となります。

    Visual StudioやVisual Studio Codeで TypeScriptを記述することで、hmV8用途の高度な補完環境を実現出来ます。

    HmV8専用の関数等々の補完ファイル

    HmV8専用に設けられている関数やオブジェクトは以下のようなTypeScript用宣言ファイルを作成すれば良いでしょう。
    TypeScriptの自分の「トリプルスラッシュ・ディレクティブ」でreference pathすれば、補完が効くようになります。

    HmV8.d.tsなどとして、
    declare var clr: any;
    
    declare namespace host {
        function lib(libname: string): any;
        function lib(libns: any, libname: string): any;
    }
    
    type THmMacroStates = (f: any)=>void;
    declare namespace hm {
        namespace Macro {
            function Eval(expression:THmMacroStates | string );
            let Var: Map<string, any>;
        }
        namespace Edit {
            let TotalText: string;
            let SelectedText: string;
            let LineText: string;
        }
    
        function debuginfo(message?: any, ...optionalParams: any[]): void;
    }
    
    interface Console {
        assert(test?: boolean, message?: string, ...optionalParams: any[]): void;
        log(message?: any, ...optionalParams: any[]): void;
    }
    
    declare var console: Console;
    
    test.tsなどとして、
    /// <reference path="hmv8.d.ts"/>
    
    let lineno: number = hm.Macro.Var["lineno"];
    

    .NET Frameworkや、C#等で自作したdll用のTypeScript宣言ファイルの生成

    入力補完上問題となりやすいのは、どちらかと言えばこちらです。
    .NET Frameworkのメソッドやプロパティ名は、
    Visual Studioの高度な入力補完が前提となっていることもあり、
    大文字小文字が入り混じった長めのプロパティ・メソッド・型で構成される傾向が高く
    入力補完に頼ることなく正確に入力していくのでは、困難と言えます。

  • WinAssemblyToTypeScriptDeclare

    そこで、.NET Frameworkのアセンブリや、自作のアセンブリを内部走査し、
    自分で利用したい「.NETの指定のクラス」を、TypeScriptで入力補完が効くように
    自動的にTypeScript宣言ファイルを生成するツールを作成しました。

    ダウンロード

    DOWNLOAD ⇒ WinAssemblyToTypeScriptDeclare.zipファイル。ver 1.351
    └更新日 2017/06/24
  • 動作環境

    • Microsoft .NET

      .NET Framework 4.7以上。

  • 使い方

    以下はコンソール(cmd.exe)での例となっています。

    コマンド概要
    WinAssemblyToTypeScriptDeclare.exe [NameSpace] [Class] -deep:[0-2] -complex
    

    となります。
    探索対象は、「.NET 4系フォルダ」と「カレントフォルダ」の.dllとなります。
    もしもC#等で自作した.dllを対象としたい場合、カレントフォルダにコピーすると良いでしょう。

  • 具体例

    「名前空間 System」の「Console」クラスをTypeScriptの宣言に
    WinAssemblyToTypeScriptDeclare.exe System Console
    
    上と同じだが、クラスや型の探索の深さが0層で済むようにする
    WinAssemblyToTypeScriptDeclare.exe System Console -deep:0
    
    名前空間に関わらず「Form」クラスをすべてTypeScritp風の宣言に
    WinAssemblyToTypeScriptDeclare.exe any Form
    

    PowerShellだと、「`1」といった文字列を引数として正しく扱えないため、
    'List`1'や'Dictionary`2'といったように、シングルクォーテーションで引数を囲ってください。

    1つのGenericパラメータがあるSystem.Collection.Generic のListクラスをTS宣言ファイルに
    WinAssemblyToTypeScriptDeclare.exe System.Collections.Generic List`1
    
    2つのGenericパラメータがあるSystem.Collection.Generic のDictionaryクラスをTS宣言ファイルに
    WinAssemblyToTypeScriptDeclare.exe System.Collections.Generic Dictionary`2
    
    宣言ファイルとしてはエラーが出る確率が高くなるが、複雑な型でも深度が許すなら極力anyにせず型情報に従う
    WinAssemblyToTypeScriptDeclare.exe.exe System Console -complex
    
    Dictionaryに関する型を探索の深さが2層までTypeScritp風の宣言に
    WinAssemblyToTypeScriptDeclare.exe System.Collections.Generic Dictionary`2 -deep:2
    
    FormとButtonの2つのクラスをTypeScript風に
    WinAssemblyToTypeScriptDeclare.exe System.Windows.Forms Form System.Windows.Forms Button
    
  • 具体例を追ってみる

    では、System.Windows.Forms FormとButtonを使う例を具体的に追ってみましょう。

    System.Windows.Forms Form と System.Windows.Forms.Button クラスをTypeScritp風の宣言に
    WinAssemblyToTypeScriptDeclare.exe  System.Windows.Forms Form  System.Windows.Forms Button > a.txt
    

    として、まずは、FormのTypeScript宣言テキストを取得します。
    これはコンソールの都合上、ShiftJISのファイルになってしまいますので、
    エディタで開いて、全体をコピーし、ClrForms.d.tsなどといったファイル名にしてみましょう。

  • d.tsの中身のエラーを切る「-skipLibCheck」オプション

    自動で生成したり、同じような定義をreference pathすると、エラーが出ますので、
    tasks.json(ご自分のTypeScriptの環境に合わせてください)で「-skipLibCheck」オプションを付けて、
    TypeScript宣言ファイル(d.ts)についてはエラーが出ないようにしましょう。

  • ソースを実際に書いてみる。入力補完が効きまくる。

    「b.ts」といったファイルにしてみる
    /// <reference path="hmv8.d.ts"/>
    /// <reference path="ClrForms.d.ts"/>
    
    let lib = host.lib("System.Windows.Forms");
    let Forms: any = lib.System.Windows.Forms;
    let Form: System.Windows.Forms.Form = Forms.Form;
    let Button: System.Windows.Forms.Button = Forms.Button;
    
    let f: System.Windows.Forms.Form = new Form();
    let b: System.Windows.Forms.Button = new Button();
    b.Text = "閉じる";
    
    function b_Click(sender: any, e: any): void {
        f.Close();
    }
    
    b.Click.connect(b_Click)
    f.Controls.Add(b);
    f.ShowDialog();
    

    入力補完が効くだけではなく、変数等をマウスで押し当てた時に、
    それが一体何なのかが.NETに沿った情報が得られるのが良い。

  • トランスパイル

    TypeScriptによってトランスパイルする(VSCodeの場合は、CTRL+SHIFT+B)

    b.jsが出来上がります。

  • マクロファイルを用意

    b.jsを読み込み実行するマクロファイルを用意しましょう。
    「b.mac」
    #JS = loaddll( hidemarudir + @"\hmV8.dll" );
    
    #_ = dllfuncw(#JS, "DoFile", currentmacrodirectory + @"\b.js" );
    
    freedll(#JS);
    
  • 実行

    ライセンス

    • WinAssemblyToTypeScriptDeclare

      MITライセンスとなります。

      ソースの場所

      Githubにソースがあります。