2017-07-06 13 views
0

関数を使用するときに正しい型を取得するためにいくつかの関数を入力しようとしています。本質的に関数は以下の通りであり、fntype引数として渡される文字列に応じてコールバック関数のargをタイプすることを目指しています。例えば 文字列リテラル引数に基づいて関数へのコールバック引数を入力します

fn(fntype: string, callback: (arg: any) => void): void; 

fn('foo', (foo) => { 
    foo.somethingInTheFooInterface; 
} 

fn('bar', (bar) => { 
    bar.somethingInTheBarInterface; 
} 

これらは私が出ているタイプは次のとおりです。物事が明示的に使用されている場合、正常に動作

type FooType = "FooType"; 
const FooType: FooType = 'FooType'; 

type BarType = 'BarType'; 
const BarType: BarType = 'BarType'; 

type ActionTypes = FooType | BarType; 

interface Action<T> { 
    type: T; 
} 

interface FooInterface extends Action<FooType> { 
    somethingOnTheFooInterface: string; 
} 

interface BarInterface extends Action<BarType> { 
    somethingOnTheBarInterface: string; 
} 

type CallbackTypes = FooInterface | BarInterface; 

type Callback<T extends CallbackTypes> = (action: T) => void; 

function fn<T extends CallbackTypes, U extends ActionTypes>(actionType: U, cb: Callback<T>): void; 

function fn (actionType, cb) { 
    cb(); 
} 

// Works fine if we explicitly type the arg 
fn(FooType, (arg: FooInterface) => { 
    arg.somethingOnTheFooInterface 
}); 

// Works fine if we define the generics when calling 
fn<FooInterface, FooType>(FooType, arg => { 
    arg.somethingOnTheFooInterface; 
}); 

しかし、tに基づいてコールバックをタイプしない彼の最初の議論:

// TypeError as arg is typed as the union type CallbackTypes 
fn(FooType, arg => { 
    arg.somethingOnTheFooInterface 
}) 

誰でもこのタイプを達成する方法についての指導を提供できれば、私は最も感謝しています。

答えて

1

私はあなたを正しく理解していれば、それは大きな過度のようです。
署名オーバーロードで目標を達成できるはずです。

関連する問題