Here's the relevant snippet of my .eslintrc.json
:
"rules": {
"@typescript-eslint/explicit-function-return-type": [
"warn",
{
"allowHigherOrderFunctions": true
}
],
}
With this config I am encountering the following:
// ❌ fails
const arrowFn1 = (): void => {
return;
};
export const arrowHoc = () => arrowFn1;
// ✅ passes
export const arrowFn2 = () => (): void => {
return;
};
I thought the top example would work. Is this expected? Thanks for any input!
This is expected - the lint rule purposely does not track references to understand what variables might be. The point of the rule is to enforce that you're defining strict contracts in your code - which means declaring return types with the declaration.
() => (): void => { ... }
is ignored with the option because the return type is trivially inferred from the declaration in code, without any IDE features - it's trivially read as "a function that returns a function that returns void"
However with () => variable
there isn't the same assurance - instead reading the code you read "a function that returns a variable" - which isn't a strict contract at all!
One could argue that the rule should ignore it because the variable is defined on the preceding line, however the rule takes a clean, consistent approach as opposed to a messy, confusing one based on lots of exceptions. For example imagine instead if your code was
import { arrowFn1 } from 'module';
export const arrowHoc = () => arrowFn1;
What's the return type of arrowHoc
? Well to figure that out first you'll need to inspect the exports of module
to determine the type of arrowFn1
, then you can know the type of arrowHoc
.
If you use variables for indirection, you need to maintain a separate, strict contract for your HOC.