2017-12-21 50 views
2

プロパティのためのフィールドをバッキングする代わりに使用する汎用メソッドのセットを作成します。私はセッターでいくつかの一般的なことをする必要があります(Angular 5のイベントエミッタを呼び出します)、毎回それを書きたくありません。TypeScriptの呼び出しプロパティの名前を取得

  1. は、私は文字列としてプロパティ名を渡すことができますが、私は ことを避けたい:

    私はこれらの3つのことを試してみました。

  2. 私はError.stackでも動作しようとしましたが、スタック トレースの解析はさまざまなブラウザで異なり、私はそれを気に入らないでしょう。

  3. 私がarguments.callee.callerを使用しようとすると、'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to themが得られます。

その他の提案はありますか?

以下の使用例。コメントは// somehow get calling property nameです。この例では、"myProperty"文字列を返すコードがあります。それは確実に生産のような場合には、プロパティ名を取得することは不可能ですので、

class ApplicationComponent { 
    private readonly properties = new Map<string, any>(); 

    protected getProperty<T>(): T { 
     const propertyName = // somehow get calling property name 
     return <T>this.properties[propertyName]; 
    } 

    protected setProperty<T>(value: T): void { 
     const propertyName = // somehow get calling property name 
     const oldValue = <T>this.properties[propertyName]; 

     if (oldValue === value) { 
      return; 
     } 

     this.properties[propertyName] = value; 

     const eventEmitter = this[`${propertyName}Change`]; 
     if (eventEmitter != null && eventEmitter instanceof EventEmitter) { 
      eventEmitter.emit(value); 
     } 
    } 
} 

class SomeComponent extends ApplicationComponent { 
    get myProperty(): SomeType { 
     return this.getProperty(); 
    } 

    set myProperty(value: SomeType) { 
     this.setProperty(value); 
    } 

    readonly myPropertyChange = new EventEmitter<SomeType>(); 
} 
+0

、任意のプロパティを傍受するES6プロキシを見て、動的に呼び出す:https://developer.mozilla.org/en-US/docs/ Web/JavaScript/Reference/Global_Objects/Proxy TypeScript側では、マップされた型と 'keyof'演算子を見てください:https://blog.mariusschulz.com/2017/01/20/typescript-2-1-mapped -タイプ –

答えて

1

冗長性は、役立ちます。 getPropertysetPropertyが特定のプロパティに影響を与える必要がある場合は、プロパティ名をパラメータとして受け入れる必要があります。

これは、property decoratorsの良い使用例です。デコレータはクラスprototypeオブジェクトとプロパティ名を受け入れます。それは、それが必要何にプロパティ記述子を設定することができます。

ランタイム実装については
function property(proto, key) { 
    Object.defineProperty(proto, key, { 
    get() { 
     return this.properties[key] 
    }, 
    set(val) { ... } 
    }); 
} 

class SomeComponent extends ApplicationComponent { 
    @property 
    myProperty: SomeType; 
} 
関連する問題