具有返回类型的类中的打字稿箭头函数声明

时间:2019-06-29 22:30:09

标签: typescript this arrow-functions typing

有人可以解释此函数语法的实际作用吗?

来自https://material-ui.com/components/drawers/

  const toggleDrawer = (side: DrawerSide, open: boolean) => (
    event: React.KeyboardEvent | React.MouseEvent,
  ) => {
    if (
      event.type === 'keydown' &&
      ((event as React.KeyboardEvent).key === 'Tab' ||
        (event as React.KeyboardEvent).key === 'Shift')
    ) {
      return;
    }

    setState({ ...state, [side]: open });
  };

https://www.typescriptlang.org/docs/handbook/functions.html

我认为第二组paren会将返回类型定义为联合类型,但是随着event传递到下面的函数中,情况似乎并非如此。

例如:

public toggleDrawer (side: DrawerSide, open: boolean):any {

我认为将其转换为类公共方法如下:


  public toggleDrawer = (side: DrawerSide, open: boolean) => (
    event: React.KeyboardEvent | React.MouseEvent,
  ) => {
   ...
  }

所以不清楚为什么它不使用其他TS方法签名中的:return语法。

在TS中带有箭头功能的这种奇特语法是否可以确保this是我们想要的类的实例?

1 个答案:

答案 0 :(得分:0)

代码正在使用higher-order functions,如注释中所建议。语法确实有点花哨,但是概念很简单。它们只是“将一个或多个函数作为参数”和/或“将函数作为结果返回”的函数。以下是一些示例:

// HO that returns a function
const first = (a: number, b: number) => {
    return () => a + b;
}
const firstHo = first(21, 21);
console.log(firstHo()); // 42

// HO that takes a function
const second = (a: number, func: (b: number, c: string) => string) => {
    console.log(func(a, "Hello World"));
}
const feed = (a: number, b: string) => `${b} : ${a}`;
second(42, feed); // Hello World : 42

//HO that takes AND returns a function
const third = (a: number, func: (b: number, c: string) => string) => {
    return (d: number) => func(a + d, "Hello World");
}
const thirdHo = third(21, feed);
console.log(thirdHo(21)); // Hello World : 42

为了清楚起见,我明确地返回了lambda,但是可以将这些函数中的任何一个简化为更像您的函数,使之难以理解:

(a: number, b: number) => () => a + b;

链接中的示例非常清楚其用法。在标记中,您会看到以下内容:

onClick={toggleDrawer(side, false)}

很显然,您是在此处设置事件处理程序的,但是toggleDrawer不是 处理程序;它是提供处理程序的函数,因此可以解决:

onClick={(event) => {...}}

至于您关于使用:return语法的问题,我不能说作者为什么这样做,但是我认为这是出于简单性和可读性。使用定义的return完全键入的示例如下所示:

toggleDrawer = (side: DrawerSide, open: boolean) : (event: React.KeyboardEvent | React.MouseEvent) => 
    (event: React.KeyboardEvent | React.MouseEvent) => {...}

这只是使其变得隐秘,而没有提供其他信息;只是复制了下一部分代码,这已经为您提供了返回函数的签名。


要解决另一个(现在已删除)的问题:我不相信它正在做的是currying函数,该函数是一种将具有多个参数的函数的求值转换为对函数序列求值的技术,每个都有一个参数。”您可能会发现有趣的是,咖喱另一个功能本身就是一个高阶功能!这是一个过于简单的示例:

// add just adds three numbers
const add = (a: number, b: number, c: number) : number => a + b + c;

// curry takes a function that takes three numbers and returns a number
// and returns a series of functions that each take a single number which
// eventually calls the given function passing the three numbers in
const curry = (f: (a: number, b: number, c: number) => number) => 
    (a: number) => (b: number) => (c: number) => f(a, b, c);

const curriedAdd = curry(add);
const addOneTo = curriedAdd(1);
const addThreeTo = addOneTo(2);
const seven = addThreeTo(4);
console.log(seven); // 7
// You could also call it like so, though it makes currying pointless
console.log(curriedAdd(1)(2)(4)); // 7

这两种技术起初看起来都是深奥的,但是它们都很强大,您可能会在日常生活中使用其中一种或两种。例如filtermapforEach都是高阶函数。您将predicate函数传递到filter中,该算法将愉快地将其应用于数组中的每个元素。 filter关心的只是您的谓词接受一个元素并返回一个布尔值。 (可选)您的谓词可以是咖喱函数。