【问题标题】:Types of parameters '__0' and 'value' are incompatible - Typescript参数'__0'和'value'的类型不兼容 - Typescript
【发布时间】:2021-10-14 05:05:05
【问题描述】:

我不是打字稿专家,我一直在试图找出以下错误:

'({ keys, fire }: { keys?: any; fire: any; }) => void' 类型的参数不可分配给 '(value: unknown, value2: unknown, set: Set ) => 无效'。 参数 '__0' 和 'value' 的类型不兼容。 类型 'unknown' 不可分配给类型 '{ keys?: any;火:任何; }'。

代码块是:

listeners.forEach(({ keys, fire }: {keys?: any; fire: any}) => {
  //some code
});

Listeners 是这样的集合:

const listeners = new Set();

我正在将一个对象推入其中:

const create = (keys) => {
  //keys can be undefined
  const listener = {
    keys,
    fire: useState()[1],
  };
  listeners.add(listener)
}

如果我从 forEach 中移除火或键,我仍然会收到相同的错误,我无法弄清楚为什么会发生这种情况。

【问题讨论】:

  • 请提供minimal reproducible example,清楚地表明您面临的问题。理想情况下,有人可以将代码放入像The TypeScript Playground (link here!) 这样的独立 IDE 中,然后立即着手解决问题,而无需首先重新创建它。所以应该没有拼写错误、不相关的错误或未声明的类型或值。
  • @jcalz 这并不能清楚地说明问题。我可以添加一堆与问题完全无关但无关紧要的其他内容。
  • 如果我将该代码放入 IDE,它会显示“listeners 不是我所知道的”(如我之前评论中的 TS Playground 链接所示)。所以在我尝试演示这个问题之前,我需要给listeners一个定义。我要求你代替我这样做,因为你会知道什么样的代码会产生你看到的错误,因为你面前有这样的代码。提供minimal reproducible example 确实需要一些努力(请考虑查看该链接中的信息),但它往往会带来更好的结果。
  • 我们需要看看listeners 的样子,因为无法重现您的错误
  • 如果listeners 是一个只包含{keys?: any, fire: any} 类型值的Set,那么您可能希望像this 一样强输入它。这能满足你的需求吗?如果是这样,我可以写一个答案;如果不是,请edit 示例来演示失败的用例。告诉我。

标签: javascript typescript destructuring


【解决方案1】:

TypeScript typings for Set 将其定义为Set<T>,这是一个带有generic 类型参数的接口,对应于集合的元素。如果您调用 the Set() constructor 而不提供任何类型信息,TypeScript 编译器将尝试推断此类型参数。

例如,如果你构造一个Set并用数组初始化它,编译器将使用数组元素来推断类型参数:

const setOfStuff = new Set([{ a: 1, b: 2 }, { a: 3, b: 4 }]);
/* const setOfStuff: Set<{
    a: number;
    b: number;
}> */

但是,如果你调用不带参数的构造函数,编译器将无法推断集合元素的类型,因此它会退回到默认值the unknown type

const oops = new Set(); 
// const oops: Set<unknown>

unknown 类型可以接受任何值,因此很容易提供unknown 类型的值。但另一方面,由于 unknown 值绝对可以是任何值,因此很难使用这样的值。编译器抱怨您将集合中的元素视为{ keys?: any; fire: any; } 类型,而它只知道它们是unknown 类型。


有时unknown 是一个合理的使用类型,但在您的情况下,您可能只打算让您的集合保存{ keys?: any; fire: any; } 类型的值,而不是其他类型。如果是这样,那么您可以在构造集合时显式指定泛型类型参数,从而对其进行强类型:

const listeners = new Set<{ keys?: any; fire: any; }>();
/* const listeners: Set<{
    keys?: any;
    fire: any;
}> */

之后,您可以调用forEach() 方法,编译器将根据需要知道每个元素的类型为{ keys?: any; fire: any; }

listeners.forEach(({ keys, fire }) => {
  //some code
}); // no error

Playground link to code

【讨论】:

    猜你喜欢
    • 2020-12-11
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    • 1970-01-01
    • 2019-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多