В коде используются функции высшего порядка, как предлагается в комментарии. Синтаксис действительно немного необычный, но концепция довольно проста. Это просто функции, которые «принимают одну или несколько функций в качестве аргументов» и / или «возвращают функцию в качестве своего результата». Вот некоторые примеры:
// 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
Я явно возвращаю лямбды для ясности, но любую из этих функций можно упростить до чего-то более похожего на вашу, что может быть немного сложнее понять:
(a: number, b: number) => () => a + b;
Пример в вашей ссылке делает его использование довольно понятным. В разметке вы увидите это:
onClick={toggleDrawer(side, false)}
Очевидно, вы устанавливаете здесь обработчик событий, но toggleDrawer
не обработчик; это функция, которая предоставляет обработчик, поэтому это разрешает:
onClick={(event) => {...}}
Что касается вашего вопроса об использовании синтаксиса :return
, я не могу сказать, почему автор сделал это таким образом, но я предполагаю, что это для простоты и удобочитаемости. Ваш пример, полностью типизированный с определенным возвратом, будет выглядеть так:
toggleDrawer = (side: DrawerSide, open: boolean) : (event: React.KeyboardEvent | React.MouseEvent) =>
(event: React.KeyboardEvent | React.MouseEvent) => {...}
Это просто делает его загадочным, не предоставляя дополнительной информации; он просто дублирует следующий фрагмент кода, который уже дает вам подпись возвращаемой функции.
Чтобы обратиться к другому (теперь удаленному) ответу: я не верю, что он делает, это функции каррирования который «представляет собой метод перевода оценки функции, которая принимает несколько аргументов, в оценку последовательности функций, каждая из которых имеет один аргумент». Что вам может показаться интересным, так это то, что функция, которая картирует другую функцию, сама по себе является функцией высшего порядка! Вот слишком упрощенный пример:
// 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
Обе эти техники поначалу кажутся эзотерическими, но обе они очень мощные, и вы, вероятно, используете одну или обе в повседневной жизни. Например, filter
, map
и forEach
- все функции высшего порядка. Вы передаете свою predicate
функцию в filter
, и алгоритм успешно применяет ее к каждому элементу в вашем массиве. filter
заботится только о том, чтобы ваш предикат принимал элемент и возвращал логическое значение. При желании ваш предикат может быть каррированной функцией.
person
ChiefTwoPencils
schedule
30.06.2019
toggleDrawer
возвращает функцию типа(event) => void
- person unional   schedule 30.06.2019