我正在使用 window.fetch在 Typescript 中,但我无法将响应直接转换为我的自定义类型:
我通过将 Promise 结果转换为中间“任何”变量来解决这个问题。
执行此操作的正确方法是什么?
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 中使用 fetch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41103360/