参数类型 '__0' 和 'value' 不兼容 - 打字稿

Types of parameters '__0' and 'value' are incompatible - Typescript

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

Argument of type '({ keys, fire }: { keys?: any; fire: any; }) => void' is not assignable to parameter of type '(value: unknown, value2: unknown, set: Set) => void'. Types of parameters '__0' and 'value' are incompatible. Type 'unknown' is not assignable to type '{ keys?: any; fire: 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 中移除火或钥匙,我仍然会遇到同样的错误,我无法弄清楚为什么会这样。

TypeScript typings for Set define it as Set<T>, an interface with a generic type parameter corresponding to the elements of the set. If you invoke 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