@kazuhoさんのJavaScriptバインディングの書き方に書かれてない、JavaScriptバインディング上級編です。Java/C++的な思想できちんと作られたクラスであれば問題ないのですが、JavaScriptのあふれんばかりのフリーダムを駆使したコードだと、ただnativeを付けたクラスを書くだけではうまく対応できなかったり、キャストしまくらないとダメだったりします。
返り値がオブジェクト型
esprimaというよくできたECMAScriptのパーサのライブラリのJSX版を作った時に遭遇した事象です。返り値が木構造のASTツリーなんですが、JSONというか、オブジェクトそのまま、という感じでした。もちろん、JSXでJSONは扱えますが、プロパティ名の短縮表記(json.member)は使えず、カッコで文字列でキーを指定した上で、asで型を明示しないとダメです。当然、コードも無駄に長く、読みにくくなります。
推奨する書き方は短く、危険だったりあまり使ってほしくない書き方は長く、というのは言語設計の中でよく行われる意思決定ですが、JSXではきちんと型を書くことでコードが綺麗になるという思想の元で作られています(要出典)。
この場合は、返り値で使われるJSONの型を定義し、nativeのメソッドからそれを返すようにすれば、result.member 形式で書けるようになるし、タイプミスも発見できるようになるので、ちょっと苦労してでもやる価値はあります。フリーダムに作られるJSONを分析して、「きっとこのタイプはこの属性しか持たないはずだ」という情報を元にクラスを定義していくのは、物によっては大変ですが・・・
書き方は、他のクラスと同じように書けばいいのですが、 native __fake__ を付けます。newはできないけど、コンパイル時に型チェックを行えるクラスというのが作れます。 final も付けるべきですかね?
native __fake__ class EsprimaBlockToken
{
    var type : string;
    var body : EsprimaToken[];
}
native __fake__ class EsprimaProgramToken extends EsprimaBlockToken
{
    var comments : EsprimaCommentToken[];
    var tokens : EsprimaSimpleToken[];
}
native class esprima {
    static function parse(src : string) : EsprimaProgramToken;
    static function parse(src : string, option : Map.<boolean>) : EsprimaProgramToken;
    static function parse(src : string, option : EsprimaOption) : EsprimaProgramToken;
} = "require('esprima')";
一点課題もあって、メンバー名に使えないプロパティ名を使いたい時どうするの?という問題です。元々のJSONを使うJSで簡易表現ができないなどの弊害があるので、元のコードの素性が悪いといえばそれまでなんですが・・・esprima.jsxでも、演算子の種類(operatorというキーの値)が取れないのは既知の問題です。
JSXで使いたいインタフェースに合わせてJS側を改造
nativeのクラス宣言の後ろに  = "require('module')"; と書くと、外部からロードするモジュールが扱えるようになる、というのは@kazuho先生のエントリーにもありますが、じつはここには何でもかけちゃいます。
Redisのnode.jsライブラリのJSXラッパーでは、既存のRedisClientクラスにメソッドを追加しています。node-redisは、Redisの2ワードコマンド(script loadとか)は、1ワード目がメソッド名、2ワード目を最初の引数に、というルールになっていますが、2ワード目によってメソッドのシグニチャがぜんぜん違うので、コンパイラの型チェックとの相性はとても良くないです。redis.jsxでは、2ワードメソッド(scriptloadとか)を個別にメソッド化することで、nativeラッパーを作成しやすくしています。
native class redis {
    static function createClient() : RedisClient;
} = '''
require('redis');
(function () {
    var RedisClient = require('redis').RedisClient;
    var twoWordsCommands = ['script exists', 'script kill', 'script flush', 'script load'];
    twoWordsCommands.forEach(function (command) {
        RedisClient.prototype[command.split(' ').join('')] = function () {
            // 新しい実装
        };
    });
})();
''';
native __fake__ class RedisClient {
    // 追加したメソッド
    function scriptexists(script : string, callback : (Error, int[]) -> void) : boolean;
    function scriptflush(callback : () -> void) : boolean;
    function scriptkill(callback : () -> void) : boolean;
    function scriptload(script : string, callback : (Error, string) -> void) : boolean;
    // 既存のメソッドも当然書けます。
    function get(key : string, callback : (Error, string) -> void) : boolean;
}
独立した関数として提供されているライブラリを、native構文の中でオブジェクトのメンバーとしてまとめて、「それぞれの関数はクラスのstatic関数である」という感じのインタフェースを与える、ということもできます (むしろそっちの方が多いかも)。
