2017-01-20 3 views
0

次typescriptですexample考えてみましょう:私は関数の名前を取り込み、いくつかの入力に取る関数を定義するために私たちを強制的に機能マッパーを定義したい。この例ではアクセスtypescriptですジェネリックキー

interface XInput { xin: number; } 
interface XOutput { xout: number; } 
interface YInput { yin: number; } 
interface YOutput { yout: number; } 

interface FMap { 
    getX: any; 
    getY: any; 
} 

interface InputMap extends FMap { 
    getX: XInput; 
    getY: YInput; 
} 

interface OutputMap extends FMap { 
    getX: XOutput; 
    getY: YOutput; 
} 

class MethodDictionary<FM, MI extends FM, MO extends FM> { 
    private _methods: any = {}; 

    define<N extends keyof FM>(name: N, fn: (a: MI[N]) => MO[N]) { 
    this._methods[name] = fn; 
    } 

    call<N extends keyof FM>(name: N, input: MI[N]) { 
    this._methods[name](input); 
    } 
} 

const mapper = new MethodDictionary<FMap, InputMap, OutputMap>(); 
mapper.define('getX', (a: XInput): XOutput => { return { xout: 0 }; }); 
mapper.call('getX', { xin: 0 }); 

をし、いくつかの出力を出す。この場合、私は 次の機能を書くために自分自身を強制したい:

interface MyMethods { 
    getX: (a: XInput) => XOutput; 
    getY: (a: YInput) => YOutput; 
} 

私は次のように書かれている可能性があり:

class OtherMapper<M> { 
    private _methods: any = {}; 

    define<N extends keyof M>(name: N, fn: M[N]) { 
    this._methods[name] = fn; 
    } 
} 

を、私は上記のように同じことを達成しているだろう。私たちが書くとしたらそれは、次のとおりです。

mapper.define('otherKey', ...) 

typescriptですが、私たちが唯一のgetX | getYのみが許可されていることをお知らせします。関数の入力または出力を変更する場合は、警告も表示されます。

しかし、私はcallメソッドの定義を書くことができませんでした。 typescriptで、私たちが使用しているタイプについて警告して、もっと簡単な契約を定義する方法を持っているように、作業例を簡略化できる方法がありますか?つまり、私たちは定義できます

interface MethodMap { 
    getX: [XInput, XOutput]; 
    getY: [YInput, YOutput]; 
} 

私たちのマッパーの唯一の一般的な議論としてそれを使用できますか?私はこれを書きたかったが、それは動作しません:

class MethodDictionary<M> { 
    private _methods: any = {}; 

    define<N extends keyof M>(name: N, fn: (a: M[N][0]) => M[N][1]) { 
    this._methods[name] = fn; 
    } 

    call<N extends keyof M>(name: N, input: M[N][0]) { 
    this._methods[name](input); 
    } 
} 

答えて

0
interface XInput { xin: number; } 
interface XOutput { xout: number; } 
interface YInput { yin: number; } 
interface YOutput { yout: number; } 

type DictionaryFunction<T> = { 
    [P in keyof T]: { 
    parameter: any; 
    returns: any; 
    } 
} 

class MethodDictionary<M extends DictionaryFunction<M>> { 
    private _methods: any = {}; 

    define<N extends keyof M>(name: N, fn: (a: M[N]['parameter']) => M[N]['returns']) { 
    this._methods[name] = fn; 
    } 

    call<N extends keyof M>(name: N, input: M[N]['parameter']) { 
    this._methods[name](input); 
    } 
} 

interface FMap { 
    getX: { 
     parameter: XInput, 
     returns: XOutput 
    }; 
    getY: { 
     parameter: YInput, 
     returns: YOutput, 
    }; 
} 

const mapper = new MethodDictionary<FMap>(); 
mapper.define('getX', (a: XInput): XOutput => { return { xout: 0 }; }); 
mapper.call('getX', { xin: 0 }); 
関連する問題