TypeScript 令人困惑的错误'对象可能是'未定义'和'类型上不存在属性'长度''

Posted

技术标签:

【中文标题】TypeScript 令人困惑的错误\'对象可能是\'未定义\'和\'类型上不存在属性\'长度\'\'【英文标题】:TypeScript confusing errors 'Object is possibly 'undefined' & 'Property 'length' does not exist on type'TypeScript 令人困惑的错误'对象可能是'未定义'和'类型上不存在属性'长度'' 【发布时间】:2021-04-07 01:25:01 【问题描述】:

我对 TypeScript 有点陌生,只是将它的功能添加到我的 React 应用程序中。所以我遇到了两个令人困惑的错误:

    最后一个“data[card.key]”上的“对象可能是'未定义'” “类型'string | any[] | IPerson'上不存在属性'length'”

我有以下代码:

const filteredCards = cards.filter(card => (card.allData || (data[card.key] && data[card.key].length)))

第一个错误很奇怪,因为我使用之前的检查来解决这个问题(如果它是“未定义”,那就是过滤方法的用途,过滤掉这张卡)。

至于第二个错误,就是检查这张卡是Array,不为空。 在“数据”的界面中我已经说过:

[key: string]: string | IPerson | Array<any> | undefined

所以编译器告诉我“data[card.key]”可能不是数组或字符串,因此没有长度。不过没关系,它只会返回“未定义”,并且这张卡也会被过滤掉。

无论如何,如果我将此代码更改为更明显的代码,它可以正常工作,不会出现打字稿错误。

const filteredCards = cards.filter(card => 
    if (card.allData) return true
    const subData = data[card.key]
    if (subData && Array.isArray(subData)) if (subData.length) return true
    return false
)

有人可以向我解释一下,这是什么问题,以便我以后可以避免这种情况?

感谢您的帮助。

【问题讨论】:

【参考方案1】:

第一个错误很奇怪,因为我使用之前的检查来解决这个问题...

我怀疑问题出在data,而不是data[card.key]。所以你需要data &amp;&amp; data[card.key] &amp;&amp;

所以编译器告诉我“data[card.key]”可能不是数组或字符串,因此没有长度。不过没关系,它只会返回“未定义”,并且这张卡也会被过滤掉。

这不是静态类型系统的工作方式。这就是 javascript 的工作原理,没错,但 TypeScript 的全部意义在于及早捕获与类型相关的错误。由于string 和(我猜)IPerson 没有length 属性,因此您不能使用length,除非您缩小类型以清除stringIPerson。例如:&amp;&amp; "length" in data[card.key] &amp;&amp; data[card.key].length

所以结合这两个你会拥有的东西:

const filteredCards = cards.filter(
    card => card.allData || (data && data[card.key] && "length" in data[card.key] && data[card.key].length)
);

由于那里的所有重复,我可能会将data[card.key] 缓存到一个变量中:

const filteredCards = cards.filter(card => 
    if (card.allData) 
        return true;
    
    const entry = data && data[card.key];
    return entry && "length" in entry && entry.length;
);

【讨论】:

不,第一个修复不起作用。 “数据”来自道具,并根据需要输入。而这个 "[key: string]: string | IPerson | Array | undefined" 告诉 typescript data[card.key] 可能是'undefined'。但我不明白为什么这是一个问题。不幸的是,第二个修复也不起作用。仍然得到同样的错误。还是谢谢 @keXXpert - 如果没有更多信息可以使用,例如minimal reproducible example,我们只能为您提供上述一般建议。

以上是关于TypeScript 令人困惑的错误'对象可能是'未定义'和'类型上不存在属性'长度''的主要内容,如果未能解决你的问题,请参考以下文章

可能简单但令人困惑的赋值错误

将 Rollup、ES 模块、TypeScript 和 JSX 连接在一起时的令人困惑的行为

令人困惑的 s3 存储桶策略上传问题

如何修复 Typescript 错误“对象可能是‘未定义’”

类,构造函数,令人困惑的方向

令人困惑的模板错误