2017-02-27 7 views
2

私はサービスロケータプロジェクトに取り組んでいます。私は、単一のパラメータを必要とする関数が渡されることを期待しています。ここでファンクションシグネチャの確認

は抜粋です:

"use strict"; 

/** Declaration types */ 
type ServiceDeclaration = Function|Object; 

export default class Pimple { 

    /** 
    * @type {{}} 
    * @private 
    */ 
    _definitions: {[key: string]: ServiceDeclaration} = {}; 

    /** 
    * Get a service instance 
    * @param {string} name 
    * @return {*} 
    */ 
    get(name: string): any { 
     if (this._definitions[name] instanceof Function) { 
      return this._definitions[name](this); 
     } 
     return this._definitions[name]; 
    } 
} 

私はこれをコンパイルしようとすると、しかし、私は次のエラーを取得する:

error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'ServiceDeclaration' has no compatible call signatures. 

私は新しいタイプの作成を試みた:

type ServiceFunction = (container: Pimple) => any; 

instanceof Functioninstanceof ServiceFunctionに変更しようとしましたが、次のエラーが表示されます。

error TS2693: 'ServiceFunction' only refers to a type, but is being used as a value here. 

私は見回しましたが、渡された関数が指定された署名と一致するかどうかを確認する例は見つかりませんでした。

答えて

4

最も簡単な解決策は、変数を使用し、活字体は、その型を推論させることです。別の方法として

get(name: string): any { 
     let f = this._definitions[name]; // here, 'f' is of type Function|Object 
     if (f instanceof Function) 
      return f(this);    // here, 'f' is of type Function 
     return f;      // here, 'f' is of type Object 
    } 

を、明示的type guardに条件をラップすることが可能である:

function isFunction(f): f is Function { 
    return f instanceof Function; 
} 

A注意:タイプObject | Functionは優雅ではありません。あなたはより良いfunction typeおよび/またはより良いobject typeを使用することを検討するかもしれません。

+1

ありがとうございました。私はいくつかのバリエーションをテストし、キー部分が 'let f = this._definitions [name];'を割り当ててから、ローカル変数をチェックして使用していることがわかりました。私は外部関数は必要ありませんでした。私は 'if(f instanceof Function){fを返します。 } ' –

+1

@AndrewShellあなたが正しいです。私は編集しました。 – Paleo

1

ここではPaleoより簡単な解決法があります。 instanceof Functionを使用する代わりに、typeof f === 'function'を使用できます。 TypeScriptのプレイグラウンドで作成した例は、hereをクリックしてください。 2つのifブランチのinput変数の上にマウスを置くと、結果が表示されます。