问题描述
当我将鼠标悬停在 VSCode 中的 ...res 上时,我收到了来自 linter 的警告:
传播类型只能从对象类型创建
当我记录 res 时,它要么是一个字符串,要么是一个对象。但是,我不知道在这种情况下如何满足 linter。
function getCookie(req: Request,key: string): string | undefined {
const {
headers: { cookie },} = req;
return (
cookie &&
cookie.split(";").reduce<string | undefined>((res,item) => {
const data = item.trim().split("=");
return <string | undefined>{ ...res,[data[0]]: data[1] };
},"")
);
}
解决方法
那么让我们分别处理 JavaScript 和 TypeScript 方面。用简单的 JavaScript 术语来说,您的函数不会执行您所描述的操作。当定义了 cookie 时,它返回一个 Record<string,string>
将 cookie 名称映射到 cookie 值,而不是特定的字符串或 false
。如果您想让它对 key
执行某些操作,那么您还没有在示例中包含该部分。
当没有定义 cookie 时,它应该返回 undefined
,但是因为您在 return 语句中测试了真实性 cookies
,它可能会返回一个空字符串。这可以通过单独进行该测试并显式返回 undefined
来解决。 (确保您的 linter 警告您在 TS 的布尔上下文中使用非布尔值。)
您传播字符串的原因是您将空字符串 ""
作为初始值传递给 Array.prototype.reduce
。由于您正在累积对象,而不是字符串,因此您的初始值应该是 {}
(一个空对象)。
这有助于我们了解 TypeScript 问题。一旦初始值被更正,你的 string | undefined
强制转换都是不必要的,并且函数整体的返回类型变为 Record<string,string> | undefined
。总之:
function getCookie(req: Request,key: string): Record<string,string> | undefined {
const {
headers: { cookie },} = req;
if (!cookie) {
return undefined;
}
return cookie.split(";").reduce<Record<string,string>>((res,item) => {
const data = item.trim().split("=");
return { ...res,[data[0]]: data[1] };
},{});
}
但是,如果您确实想查找特定的 key
并返回其值,则数组化简器不是最佳方法,您的函数看起来会大不相同。