【问题标题】:Why does typescript think my any is an unknown?为什么 typescript 认为我的 any 是未知数?
【发布时间】:2020-11-12 14:25:21
【问题描述】:

我有以下

sortByCounter = (ps: any) => {
    return Object.values(ps).sort(
      (a: any, b: any) => {
        return (a.Counter >= b.Counter) 
        ? -1 : 1;
      }
    );
}

这导致打字稿说

Property 'Counter' does not exist on
type 'unknown'.

我之所以不只是为带有 Counter 的对象创建一个接口,是因为对象上还有很多其他可能的属性。

我已经尝试过How do I dynamically assign properties to an object in TypeScript? 中描述的 LooseObject 解决方案,但是(将所有任何都替换为 LooseObject)但它仍然一直告诉我 Counter 在未知类型上不存在。

事实上,我还没有在任何地方使用该代码,只是它的存在(VS Code 说这很好)导致 typescript 使我的应用程序崩溃。

【问题讨论】:

  • 如果你要使用这样的代码,我想知道你为什么要使用 TypeScript?最好正确键入函数
  • 你在你的包 json 中使用了哪个版本的打字稿,VS 代码使用的是哪个版本?因为如果您将代码复制并粘贴到打字稿游乐场,它会正常工作
  • 警告 - 您的排序比较器有问题。它从不处理相等性,所以它只产生两个值,更大或更小。两个相等的值会被错误地认为是“更大的”。这可能会欺骗排序算法,并在排序时导致难以发现和诊断的细微错误。
  • @user254694 比较器函数需要生成 三个 值 - 更大(负)、更小(正)和等于(零)。您只产生两个值 - 更大和更小。相等情况的处理就好像它更大一样。因此,您的比较器函数不再对称 - compare(a, b) 不一定与 compare(b, a) 相反。排序算法可能采取的任何捷径都依赖于关于项目如何相互排序的推断,以最小化所做的比较。但是,错误的比较算法可能会导致推理失败。
  • @user254694 在 VS 代码中打开 *.ts 文件并查看 VS 代码的右下角,你应该可以找到)

标签: typescript


【解决方案1】:

只有当ps 是一个object,其值都是objects 且具有Counter 属性时,调用这个函数才有意义。其他任何事情都会导致运行时错误。为什么不告诉 typescript 正确的类型?

const sortByCounter = (ps: Record<PropertyKey, {Counter: number}>) => {
    return Object.values(ps).sort(
      (a, b) => {
        return b.Counter - a.Counter;
      }
    );
}

Record&lt;PropertyKey, {Counter: number}&gt; 类型表示这是一个对象,其键可以是任何有效的对象键 (string | number | symbol),其值是具有 number 属性 Counter 的对象。

ab 都被正确推断为 {Counter: number}

正如@VLAZ 所解释的,您希望比较返回正负和相等的输出,因此您可以只使用减法而不是三进制。

【讨论】:

  • 有时人们并不知道某事物中可能包含的所有数据,而只知道其中的一些数据。这就是为什么我不想告诉 typescript 它是什么类型,因为我不确定对象中可以存在的所有数据,只有我想要的数据。
  • 对,所以你告诉 typescript 你想要的数据。它可以包含其他属性,这不是问题。我们告诉 typescript 数据需要匹配的最小值。如果它至少不具备这些最低属性,那就是个问题。这将是一个运行时错误。
猜你喜欢
  • 2018-10-15
  • 2022-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-13
  • 2023-02-11
  • 2020-05-12
  • 1970-01-01
相关资源
最近更新 更多