如何在非类 TypeScript 接口中防止 "@typescript-eslint/unbound method" 错误?

17

以下代码没有使用类或 this。如何防止在仅有函数(没有类)的代码中出现typescript-eslint错误?我知道可以全局禁用规则,但该规则对于类代码非常有用。我知道可以一行一行地禁用它,但是考虑到在TS接口中定义回调函数是多么普遍,这似乎很麻烦。还有其他方法吗?

下面是一个问题的简化示例:

interface FooProps {
  bar(): void;
}

export function foo(props: FooProps) {
  const { bar } = props;
  // ^^^ Avoid referencing unbound methods which may cause unintentional scoping of `this`.
  //     eslint(@typescript-eslint/unbound-method)
  return bar;
}
2个回答

37
这个问题非常容易解决,只需将bar(): void替换为bar: () => void即可。

示例:

interface FooProps {
  bar: () => void;
}

export function foo(props: FooProps) {
  const { bar } = props;  // no lint error
  return bar;
}

我一直想知道为什么TypeScript接口中的函数值成员有两种不同的语法。我一直认为这两种语法具有相同的含义。现在我知道得更清楚了:似乎bar(): void语法表示“类成员函数”,而bar: () => void表示“函数值属性,不使用this”。

在这里留下一个问答对,以便下一个人不会像我一样浪费半个小时。


6
我希望我只浪费了半个小时! - HaveSpacesuit
1
所以最终,一切都归结于语法?? 多么愚蠢。我要禁用此规则。此外,我认为你对接口中函数的初始假设是正确的。我在任何地方都没有看到typescript会对接口中函数类型的实现做出任何假设。根据我的经验,接口只告诉您对象的形状,而不是它将如何实现。使用常规函数语法声明函数类型并不意味着函数内部的“this”总是与包含该函数的对象相关联。 - smac89
1
@Justin Grant。感谢您制作了一个问答对。一些人在SO上并没有意识到这是该平台的一个功能之一。 - Archimedes Trajano
这在NextJS中不起作用;它抱怨函数不可序列化。我不得不添加this: void作为参数。 - undefined

1
以上方法可以解决eslint错误,但是如果该函数作为NextJs/React的prop使用,将会触发另一个错误:
引入文件中的组件props必须是可序列化的,"bar"是无效的.ts(71007)
在我的情况下,解决方案是:
interface FooProps {
  bar(this: void): void;
}

export function foo(props: FooProps) {
  const { bar } = props;  // no lint error
  return bar;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接