I've noticed something in online articles lately: arrow functions everywhere. It's as if function became a dirty word
overnight, and every function declaration got replaced with const myFunc = () => {}. While arrow functions are
undeniably useful, I think we've swung too far in the other direction.
Let me be clear upfront—there are absolutely cases where arrow functions shine and others where function declarations are better. If you want a comprehensive breakdown of the differences, James Sinclair's article on the differences between ordinary functions and arrow functions is an excellent reference.
But when there isn't a clear technical winner, many developers still default to arrow functions. The assumption seems to be that they're more concise. Let's test that assumption.
The "shorter" myth
Here's a simple function declaration:
function calculate() {
// implementation
}
And here's the arrow function equivalent:
const calculate = () => {
// implementation
};
Count the characters of the first line: 22 vs 35. The arrow function is actually longer. If we ignore the function name (calculate), it's
13 vs 16 characters. The "conciseness" argument falls apart pretty quickly when you're dealing with named functions.
When syntax gets in the way
I recently came across a perfect example of this in a TypeScript article about advanced type manipulation features. The author needed to demonstrate generic functions and wrote:
const sendEvent = <E extends EventName,>(
event: E,
payload: HomeEvents[E]
) => { /* ... */ };
Notice that trailing comma after EventName? The author had to dedicate an entire sidebar to explain why it's
there—because TypeScript and JSX syntax clash when using arrow functions with generics. The comma tells the parser it's
looking at a generic type, not a JSX element.
The solution? Use a function declaration:
function sendEvent<E extends EventName>(
event: E,
payload: HomeEvents[E]
) { /* ... */ }
Clean, clear, and no syntactic gymnastics required. The reader can focus on the actual TypeScript concepts being taught instead of wrestling with parser ambiguities.
A modest proposal
Here's what I suggest: make function declarations your default choice. Reach for arrow functions when you have a
specific reason—when you need lexical this, when you're writing a short callback, when you're working in a functional
style.
But if you're just writing a regular function that does some work and returns a result? Consider the humble function
keyword. Sometimes the old ways persist because they just work better.
The next time you type const myFunction = () => {, pause for a second. Ask yourself: is there a compelling reason to
use an arrow function here, or am I just following a trend?
Happy coding!