Bind 是有害的

::: tip 译者注:在这个 PR 下,已经解决 bindcallapply 类型正确推导的问题,预计在 3.2 版本中发布。 :::

这是在 lib.d.tsbind 的定义:

bind(thisArg: any, ...argArray: any[]): any

你可以看到他的返回值是 any,这意味着在函数上调用 bind 会导致你在原始函数调用签名上将会完全失去类型的安全检查。

如下所示:

function twoParams(a: number, b: number) {
  return a + b;
}

let curryOne = twoParams.bind(null, 123);
curryOne(456); // ok
curryOne('456'); // ok

一个更好的方式的是使用类型注解的箭头函数:

function twoParams(a: number, b: number) {
  return a + b;
}

let curryOne = (x: number) => twoParams(123, x);
curryOne(456); // ok
curryOne('456'); // Error

如果你想用一个柯里化的函数,你可以看看此章节

类成员

另一个常见用途是在传递类函数时使用 bind 来确保 this 的正确值,不要这么做。

在接下来的示例中,如果你使用了 bind,你将会失去函数参数的类型安全:

class Adder {
  constructor(public a: string) {}

  add(b: string): string {
    return this.a + b;
  }
}

function useAdd(add: (x: number) => number) {
  return add(456);
}

let adder = new Adder('mary had a little 🐑');
useAdd(adder.add.bind(adder)); // 没有编译的错误
useAdd(x => adder.add(x)); // Error: number 不能分配给 string

如果你想传递一个类成员的函数,使用箭头函数。例如:

class Adder {
  constructor(public a: string) {}

  // 此时,这个函数可以安全传递
  add = (b: string): string => {
    return this.a + b;
  };
}

另一种方法是手动指定要绑定的变量的类型:

const add: typeof adder.add = adder.add.bind(adder);

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「IT平头哥联盟」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

results matching ""

    No results matching ""