I've begun working on a project with typescript and eslint. Issue is, eslint gives me an unexpected error on what seems to be a properly declared function
import React, { useState } from 'react';
type Props = {
options: Array<string>
};
const Switch: React.FC<Props> = (props: Props) => {
const [choice, setChoice] = useState<number>(0);
// eslint gives error @ following function
const handleSwitchChange = ():void => {
choice + 1 >= options.length ? setChoice(0) : setChoice(choice + 1)
};
return (
<div>{options[choice]}</div>
<button onClick={handleSwitchChange}>Change choice</button>
);
};
Now this works as expected, but despite the fact the function I'm passing to is of declared type void
eslint gives me the following error:
Expected an assignment or function call and instead saw an expression.
Now I don't want to just disable the rule, but I don't see anything inherently wrong with the code. Is there any way to write the function properly so es-lint doesn't complain?
The specific eslint module which raises the error
{
"resource": "<PATH CENSORED>/src/components/forms/Switch.tsx",
"owner": "eslint",
"code": "@typescript-eslint/no-unused-expressions",
"severity": 8,
"message": "Expected an assignment or function call and instead saw an expression.",
"source": "eslint",
"startLineNumber": 12,
"startColumn": 5,
"endLineNumber": 12,
"endColumn": 85
}
When you have an arrow function with curly braces, its body must include at least one statement (as the error message suggests, an assignment or function call, or an if
or return
statement or something similar):
const handleSwitchChange = {
// Statements must go here
};
You've actually given an expression that (type checking aside) could appear on the right-hand side of an assignment or a function parameter:
// Syntactically valid, not necessarily meaningful
const hypothetical = choice + 1 >= options.length ? setChoice(0) : setChoice(choice + 1);
someFunction(choice + 1 >= options.length ? setChoice(0) : setChoice(choice + 1));
You have a couple of options. Easiest is to change the arrow function to a form that takes an expression by removing the curly braces
const handleSwitchChange = (): void =>
choice + 1 >= options.length ? setChoice(0) : setChoice(choice + 1);
There are various ways to refactor this to look more like a statement, like replacing the ternary operator with an if
statement, or by moving the function up to the top level.
// Equally valid with or without curly braces
// (Curly braces explicitly ignore the return value)
const handleSwitchChange = (): void => {
setChoice(choice + 1 >= options.length ? 0 : choice + 1);
};