2016-10-26 9 views
15

ReactとReduxを使用していて、インターフェイスとして指定されたアクションタイプを使用しているため、型削減のためにタグ付きの共用体を利用できます。TypeScriptの矢印関数で戻り値の型を指定する

だから、私はこのように見えるの型宣言を持っている:

interface AddTodoAction { 
    type: "ADD_TODO", 
    text: string 
}; 

interface DeleteTodoAction { 
    type: "DELETE_TODO", 
    id: number 
} 

type TodoAction = AddTodoAction | DeleteTodoAction 

私はこれらのアクションを作成するヘルパー関数を作成したいのですが、私はこのために、矢印の機能を使用する傾向があります。私はこれを書いている場合:

export const addTodo1 = (text: string) => ({ 
    type: "ADD_TODO", 
    text 
}); 

コンパイラは、戻り値の型が明示的に指定されていないので、これは有効なAddTodoActionであることを確認することで任意のヘルプを提供することはできません。

export const addTodo2: (text: string) => AddTodoAction = (text: string) => ({ 
    type: "ADD_TODO", 
    text 
}) 

しかし、これは、関数の引数を2回指定する必要があるため、冗長で読みにくくなります。

矢印表記を使用するときに、戻り値の型を明示的に指定する方法はありますか?私はこれをしようと思っている

:この場合

export const addTodo3 = (text: string) => <AddTodoAction>({ 
    type: "ADD_TODO", 
    text 
}) 

、コンパイラはAddTodoActionとして戻り値の型を推論するが、私が戻っていたオブジェクトが適切なのすべてを持っていることを検証しませんですフィールド。

私は別の関数の構文に切り替えることにより、この問題を解決することができます:

export const addTodo4 = function(text: string): AddTodoAction { 
    return { 
     type: "ADD_TODO", 
     text 
    } 
} 

export function addTodo5(text: string): AddTodoAction { 
    return { 
     type: "ADD_TODO", 
     text 
    } 
} 

これらのいずれかの方法は、コンパイラが正しい戻り値の型を使用して、私が適切にすべてのフィールドを設定していることを強制するために発生しますが、彼らはありますまたもっと冗長で、 'this'が関数で処理される方法を変更します(これは問題ではないかもしれません)。

これを行う最善の方法についてアドバイスはありますか?

+1

'getTitle =():string => '状態リスト' ' –

答えて

22

まず、あなたの元の質問から、次の表記法を考えてみます。

export const addTodo3 = (text: string) => <AddTodoAction>({ 
    type: "ADD_TODO", 
    text 
}) 

この表記を使用して、タイプAddTodoActionに返されたオブジェクトを型キャスト。ただし、関数の宣言された戻り値の型は未定義です(コンパイラは戻り値の型として暗黙にanyと仮定します)。予想コンパイラエラーをもたらす必要性を省略し、ここで

export const addTodo3 = (text: string): AddTodoAction => ({ 
    type: "ADD_TODO", 
    text: text 
}) 

代わりに以下の表記を使用します。例えば、textプロパティを省略すると、次の(所望の)エラーが発生します:

Type '{ type: "ADD_TODO"; }' is not assignable to type 'TodoAction'. 
    Type '{ type: "ADD_TODO"; }' is not assignable to type 'DeleteTodoAction'. 
    Types of property 'type' are incompatible. 
     Type '"ADD_TODO"' is not assignable to type '"DELETE_TODO"'. 

をまたplayground example参照。

+0

これはまさに私が探していた表記です。残念なことに、Visual Studioコードは、私の期待に合った方法でこれを強調表示しませんが、コンパイラはそれを理解しているようです。 –

0

私はあなたのインターフェイスのすべてのネストされたタイプの、そしてあなただけの、そのタイプを指定する必要があり、あなたの最善の策は、右のタイプを持っているあなたの機能のためのインタフェースを作成することではありませんと思う:

interface AddTodoAction { 
    type: "ADD_TODO", 
    text: string 
}; 

interface AddTodoActionCreator { 
    (text: string): AddTodoAction; 
}; 

export const addTodo: AddTodoActionCreator = (text) => ({ 
    type: "ADD_TODO", 
    text 
}); 
+1

この例ではジェネリックをどのように使用しますか? AddTodoActionCreator

関連する問題