【问题标题】:Array will never be empty but typescript does not know数组永远不会为空,但打字稿不知道
【发布时间】:2021-02-16 01:15:16
【问题描述】:

我收到此错误 Expected at least 1 arguments, but got 0 or more 来自:

    if (initialValues.length > 0) {
      return Object.assign(...initialValues);
    }

我猜它抱怨initialValues 可能是空的。但是,if 条件保证它不会为空。我该怎么做才能让 typescript 实现这一点?

【问题讨论】:

  • 嗯,这不完全是 this question 的重复,但它密切相关。我已将其标记为重复,但我会撤消它。
  • 仅供参考,我已经更新了下面的答案,以展示如何根据需要使用类型。

标签: typescript


【解决方案1】:

允许 length check as a type guard 被认为“太复杂”而无法添加到 TypeScript(感谢 @jcalz 提供链接!)。

您至少可以采取三种方法:

解构并明确提供目标

由于它不是从 length 检查中获取的,我可能会明确地给它目标对象,如下所示:

const [target, ...sources] = initialValues;
if (target) {
    return Object.assign(target, ...sources);
}

很高兴。

Playground link

定义为非空数组

This answer 展示了如何为非空数组定义类型:

type NonEmptyArray<T> = [T, ...T[]];

如果initialValues 在编译时已知总是至少有一个元素,则使用该类型定义它:

let initialValues: NonEmptyArray<YourObjectType>;

然后你可以删除if,因为你知道它永远是真的:

return Object.assign(...initialValues);

使用类型保护

但如果它可能为空并且需要运行时检查,则可以定义类型保护函数:

function isNotEmpty<T>(arr: T[]): arr is NonEmptyArray<T> {
    return arr.length > 0;
}

那就是:

if (isNotEmpty(initialValues)) {
    return Object.assign(...initialValues);
}

非常感谢 @jcalz@VLAZ 帮助解答这个问题。

【讨论】:

  • 一个奇怪的观察 - I tried a different approach 使用类型保护 + minimum length array 但编译器会抛出同样的错误。
  • @VLAZ - 是的,我也尝试过这样处理(尽管以不同的方式,[object] &amp; object[],但无论如何都无法正常工作)。不知道为什么。
  • @VLAZ 仅仅添加一个键为0 的属性并不意味着TypeScript 中的length 属性有任何意义(如果这发生在任何正常 i> 对象类型,因此当交叉点的一侧是数组时,它不会神奇地发生也就不足为奇了)。您可以使用this method 来表示编译器实际上可以理解的内容
  • 如果您想修改答案以包含该信息,我可以。我不会自己添加答案。
  • 如果重要的话,microsoft/TypeScript#38000 是被拒绝的请求,让 array.length &gt; 0 充当类型保护。
猜你喜欢
  • 2016-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-09
  • 2021-06-02
  • 2016-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多