[解決済み] TypeScriptでfetchを使う方法
2022-03-08 09:54:45
質問
を使っています。 ウィンドウズ・フェッチ をTypescriptで作成しましたが、レスポンスをカスタムタイプに直接キャストすることができません。
私は、Promiseの結果を中間変数'any'にキャストすることで、この問題を回避しています。
これを行うには、どのような方法が正しいのでしょうか?
import { Actor } from './models/actor';
fetch(`http://swapi.co/api/people/1/`)
.then(res => res.json())
.then(res => {
// this is not allowed
// let a:Actor = <Actor>res;
// I use an intermediate variable a to get around this...
let a:any = res;
let b:Actor = <Actor>a;
})
解決方法は?
基本的なものから、リクエストやエラー処理の後に変換を追加するものまで、いくつかの例を以下に示します。
基本的なことです。
// Implementation code where T is the returned data shape
function api<T>(url: string): Promise<T> {
return fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(response.statusText)
}
return response.json<T>()
})
}
// Consumer
api<{ title: string; message: string }>('v1/posts/1')
.then(({ title, message }) => {
console.log(title, message)
})
.catch(error => {
/* show error message */
})
データ変換を行います。
例えば、トップレベルのデータ属性をアンラップするなど、コンシューマに渡す前にデータを調整する必要がある場合がよくあります。これは簡単なことです。
function api<T>(url: string): Promise<T> {
return fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(response.statusText)
}
return response.json<{ data: T }>()
})
.then(data => { /* <-- data inferred as { data: T }*/
return data.data
})
}
// Consumer - consumer remains the same
api<{ title: string; message: string }>('v1/posts/1')
.then(({ title, message }) => {
console.log(title, message)
})
.catch(error => {
/* show error message */
})
エラー処理を行います。
このサービス内で直接エラーキャッチをするのではなく、バブルを発生させるようにすればいいというのが私の意見ですが、必要であれば、次のようにすればいいでしょう。
function api<T>(url: string): Promise<T> {
return fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(response.statusText)
}
return response.json<{ data: T }>()
})
.then(data => {
return data.data
})
.catch((error: Error) => {
externalErrorLogging.error(error) /* <-- made up logging service */
throw error /* <-- rethrow the error so consumer can still catch it */
})
}
// Consumer - consumer remains the same
api<{ title: string; message: string }>('v1/posts/1')
.then(({ title, message }) => {
console.log(title, message)
})
.catch(error => {
/* show error message */
})
編集
しばらく前にこの回答を書いてから、いくつかの変更がありました。コメントにもあるように
response.json<T>
は有効ではなくなりました。どこで削除されたのかが分からないので、よく分かりません。
それ以降のリリースでは、できます。
// Standard variation
function api<T>(url: string): Promise<T> {
return fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(response.statusText)
}
return response.json() as Promise<T>
})
}
// For the "unwrapping" variation
function api<T>(url: string): Promise<T> {
return fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(response.statusText)
}
return response.json() as Promise<{ data: T }>
})
.then(data => {
return data.data
})
}
関連
-
[解決済み】Typescriptで、! (エクスクラメーションマーク/バン)演算子でメンバを再参照するのは?
-
[解決済み] TypeScriptで文字列を数値に変換する方法とは?
-
[解決済み] TypeScript で `window` に新しいプロパティを明示的に設定するにはどうすればよいですか?
-
[解決済み] TypeScriptでの取得と設定
-
[解決済み] TypeScriptでパラメータとして強く型付けされた関数は可能か?
-
[解決済み] TypeScriptでオブジェクトに動的にプロパティを割り当てるには?
-
[解決済み] TypeScriptで配列の項目を削除するには?
-
[解決済み] TypeScriptで文字列をenumに変換するには?
-
[解決済み】TypeScriptのインターフェースと型について
-
[解決済み】TypeScriptの "not assignable to parameter of type never "エラーとは?
最新
-
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: スプレッド型はオブジェクト型からしか作成できない
-
[解決済み] TSLintの "文字列リテラルによるオブジェクトアクセス "を回避するためのコードの書き換え方法
-
[解決済み] TypeScriptでfetchを使う方法
-
[解決済み] TypeScriptの "*.d.ts "について
-
[解決済み] Typescript オブジェクトのインデックス付きメンバの型を強制する?
-
[解決済み] タイプスクリプトのレコードタイプとは何ですか?
-
[解決済み】ランタイムにオブジェクトのクラス名を取得する
-
[解決済み】TypeScriptとフィールドイニシャライザー
-
[解決済み】文字列の値を持つenumの作成
-
[解決済み】WebStorm/PhpStormのダブルクォートでTypeScriptの自動インポートを行う。