Код использует функции высшего порядка , как предлагается в комментарии. Синтаксис действительно немного причудливый, но концепция довольно проста. Это просто функции, которые «принимают одну или несколько функций в качестве аргументов» и / или «возвращают функцию в качестве результата». Вот несколько примеров:
// 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
, - это то, что ваш предикат принимает элемент и возвращает логическое значение. При желании ваш предикат может быть функцией карри.