在 Typescript 中使用 fetch 进行数据转换
Using fetch in Typescript with data transformations
我正在尝试将 js 代码转换为 ts,并且我有这个:
function api<T>(url: string): Promise<T> {
return fetch(url)
.then((res) => {
return res.json().then((resJson: T) => ({
ok: res.ok,
status: res.status,
body: resJson,
}));
})
.then((res) => {
if (res.ok) {
return res.body;
}
return Promise.reject({
status: res.status,
message: res.body.message,
});
});
}
我不知道如何解决
的问题
message: res.body.message // Property 'message' does not exist on type 'T'
仅当 res.ok === false 时,我的正文响应才包含“消息”属性 作为可选内容。这个案子怎么破?
大概用量:
type ResBody = {
success: boolean;
message?: string;
data?: string[];
};
api<ResBody>("https://example.com")
.then(({ success, data }) => {
console.log(success, data);
})
.catch((err) => {
console.log(err.message, err.status)
});
Promise 类型有一个泛型参数T
,这样你就可以声明异步函数的return 类型。这允许您以类型安全的方式引用该 return 值。
您的第一个 then
return 对象 body
分配了一个 T
类型的值,然后您的下一个 then
将其作为其对象res
输入。这意味着 res
被推断为具有 T
类型的 body
。然后您引用 res.body.message
,但您没有在哪里声明类型 T
是具有字段 message
.
的类型
当您在 function api<T>
声明中声明泛型参数 T
时,您需要这样做,如下所示:
function api<T extends ResBody>(url: string): Promise<T> {
return fetch(url)
.then((res) => {
return res.json().then((resJson: T) => ({
ok: res.ok,
status: res.status,
body: resJson,
}));
})
.then((res) => {
if (res.ok) {
return res.body;
}
return Promise.reject({
status: res.status,
message: res.body.message,
});
});
}
T extends ResBody
告诉 Typescript 通用类型 T
,无论它最终是什么,都将是 ResBody 或其子类型,因此将有一个可选的 message
字段类型 string
.
你可以比这更通用,即如果 T
可以是 任何 类型,其中包含 message
字段,如下所示:
function api<T extends {message?: string}>(url: string): Promise<T> {
return fetch(url)
.then((res) => {
return res.json().then((resJson: T) => ({
ok: res.ok,
status: res.status,
body: resJson,
}));
})
.then((res) => {
if (res.ok) {
return res.body;
}
return Promise.reject({
status: res.status,
message: res.body.message,
});
});
}
T extends {message?: string}
告诉 Typescript 泛型类型 T
,无论它最终是什么,都有一个类型为 string
.
的可选 message
字段
我正在尝试将 js 代码转换为 ts,并且我有这个:
function api<T>(url: string): Promise<T> {
return fetch(url)
.then((res) => {
return res.json().then((resJson: T) => ({
ok: res.ok,
status: res.status,
body: resJson,
}));
})
.then((res) => {
if (res.ok) {
return res.body;
}
return Promise.reject({
status: res.status,
message: res.body.message,
});
});
}
我不知道如何解决
的问题message: res.body.message // Property 'message' does not exist on type 'T'
仅当 res.ok === false 时,我的正文响应才包含“消息”属性 作为可选内容。这个案子怎么破? 大概用量:
type ResBody = {
success: boolean;
message?: string;
data?: string[];
};
api<ResBody>("https://example.com")
.then(({ success, data }) => {
console.log(success, data);
})
.catch((err) => {
console.log(err.message, err.status)
});
Promise 类型有一个泛型参数T
,这样你就可以声明异步函数的return 类型。这允许您以类型安全的方式引用该 return 值。
您的第一个 then
return 对象 body
分配了一个 T
类型的值,然后您的下一个 then
将其作为其对象res
输入。这意味着 res
被推断为具有 T
类型的 body
。然后您引用 res.body.message
,但您没有在哪里声明类型 T
是具有字段 message
.
当您在 function api<T>
声明中声明泛型参数 T
时,您需要这样做,如下所示:
function api<T extends ResBody>(url: string): Promise<T> {
return fetch(url)
.then((res) => {
return res.json().then((resJson: T) => ({
ok: res.ok,
status: res.status,
body: resJson,
}));
})
.then((res) => {
if (res.ok) {
return res.body;
}
return Promise.reject({
status: res.status,
message: res.body.message,
});
});
}
T extends ResBody
告诉 Typescript 通用类型 T
,无论它最终是什么,都将是 ResBody 或其子类型,因此将有一个可选的 message
字段类型 string
.
你可以比这更通用,即如果 T
可以是 任何 类型,其中包含 message
字段,如下所示:
function api<T extends {message?: string}>(url: string): Promise<T> {
return fetch(url)
.then((res) => {
return res.json().then((resJson: T) => ({
ok: res.ok,
status: res.status,
body: resJson,
}));
})
.then((res) => {
if (res.ok) {
return res.body;
}
return Promise.reject({
status: res.status,
message: res.body.message,
});
});
}
T extends {message?: string}
告诉 Typescript 泛型类型 T
,无论它最终是什么,都有一个类型为 string
.
message
字段