[解決済み] TypeScriptのarrow関数で戻り値の型を指定する
質問
私はReactとReduxを使用しており、私のリデューサーが型安全性を向上させるためにタグ付きユニオン型を利用できるように、インターフェイスとして指定されたアクションタイプを持っています。
ということで、以下のような型宣言をしています。
interface AddTodoAction {
type: "ADD_TODO",
text: string
};
interface DeleteTodoAction {
type: "DELETE_TODO",
id: number
}
type TodoAction = AddTodoAction | DeleteTodoAction
これらのアクションを作るヘルパー関数を作りたいのですが、これにはarrow関数を使うことが多いですね。これを書くと
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
は関数内で処理されます(これは問題ではないかもしれませんが。)
何か良い方法はないでしょうか?
どのように解決するのですか?
まず、最初の質問で出てきた以下の表記を考えてみましょう。
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"'.
また プレイグラウンドの例 .
関連
-
[解決済み] TypeScriptで文字列を数値に変換する方法とは?
-
[解決済み] TypeScript で `window` に新しいプロパティを明示的に設定するにはどうすればよいですか?
-
[解決済み] TypeScriptでの取得と設定
-
[解決済み] TypeScriptでパラメータとして強く型付けされた関数は可能か?
-
[解決済み] クラス定数を実装するには?
-
[解決済み] Typescript によるインターフェース型チェック
-
[解決済み] タイプスクリプトのレコードタイプとは何ですか?
-
[解決済み】TypeScriptのインターフェースと型について
-
[解決済み】TypeScriptとフィールドイニシャライザー
-
[解決済み】Typescript インターフェースのデフォルト値
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Typescript : require文はimport文の一部ではない
-
[解決済み] グローバル定数の定義
-
[解決済み] 2つのインターフェイスを統合する
-
ts 学習日記1 AssertionError [ERR_ASSERTION]: タスク関数を指定する必要があります
-
[解決済み] Object literal may only specify known properties" というエラーが発生するのはなぜですか?
-
[解決済み] TypeScriptの非同期関数でプロミスを返す
-
[解決済み] ジェネリックスを使用したTypescriptのarrow関数の構文はどのようになっていますか?
-
[解決済み】TypeScriptの "not assignable to parameter of type never "エラーとは?
-
[解決済み】TypeScriptとフィールドイニシャライザー
-
[解決済み】ブロックに`@ts-ignore`を使用するには?