Skip to content

Commit 072afa5

Browse files
committed
feat(eslint-plugin): allow explicit variable type with arrow functions
Fixes typescript-eslint#149
1 parent ecc9631 commit 072afa5

File tree

3 files changed

+85
-1
lines changed

3 files changed

+85
-1
lines changed

Diff for: packages/eslint-plugin/docs/rules/explicit-function-return-type.md

+14
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,20 @@ node.addEventListener('click', function() {});
8484
const foo = arr.map(i => i * i);
8585
```
8686

87+
### allowTypedFunctionExpressions
88+
89+
Examples of additional **correct** code for this rule with `{ allowTypedFunctionExpressions: true }`:
90+
91+
```ts
92+
type FuncType = () => string;
93+
94+
let arrowFn: FuncType = () => 'test';
95+
96+
let funcExpr: FuncType = function() {
97+
return 'test';
98+
};
99+
```
100+
87101
## When Not To Use It
88102

89103
If you don't wish to prevent calling code from using function return values in unexpected ways, then

Diff for: packages/eslint-plugin/src/rules/explicit-function-return-type.ts

+25-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import * as util from '../util';
99
type Options = [
1010
{
1111
allowExpressions?: boolean;
12+
allowTypedFunctionExpressions?: boolean;
1213
}
1314
];
1415
type MessageIds = 'missingReturnType';
@@ -32,6 +33,9 @@ export default util.createRule<Options, MessageIds>({
3233
properties: {
3334
allowExpressions: {
3435
type: 'boolean'
36+
},
37+
allowTypedFunctionExpressions: {
38+
type: 'boolean'
3539
}
3640
},
3741
additionalProperties: false
@@ -40,7 +44,8 @@ export default util.createRule<Options, MessageIds>({
4044
},
4145
defaultOptions: [
4246
{
43-
allowExpressions: true
47+
allowExpressions: true,
48+
allowTypedFunctionExpressions: false
4449
}
4550
],
4651
create(context, [options]) {
@@ -65,6 +70,17 @@ export default util.createRule<Options, MessageIds>({
6570
);
6671
}
6772

73+
/**
74+
* Checks if the parent of a function expression has a type annotation.
75+
* @param parent The parent of a function expression node
76+
*/
77+
function hasTypeAnnotation(parent: TSESTree.Node): boolean {
78+
return (
79+
parent.type === AST_NODE_TYPES.VariableDeclarator &&
80+
!!parent.id.typeAnnotation
81+
);
82+
}
83+
6884
/**
6985
* Checks if a function declaration/expression has a return type.
7086
* @param node The node representing a function.
@@ -108,6 +124,14 @@ export default util.createRule<Options, MessageIds>({
108124
return;
109125
}
110126

127+
if (
128+
options.allowTypedFunctionExpressions &&
129+
node.parent &&
130+
hasTypeAnnotation(node.parent)
131+
) {
132+
return;
133+
}
134+
111135
checkFunctionReturnType(node);
112136
}
113137

Diff for: packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts

+46
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,28 @@ function test() {
9191
allowExpressions: true
9292
}
9393
]
94+
},
95+
{
96+
filename: 'test.ts',
97+
code: `
98+
var arrowFn: Foo = () => 'test';
99+
`,
100+
options: [
101+
{
102+
allowTypedFunctionExpressions: true
103+
}
104+
]
105+
},
106+
{
107+
filename: 'test.ts',
108+
code: `
109+
var funcExpr: Foo = function() { return 'test'; };
110+
`,
111+
options: [
112+
{
113+
allowTypedFunctionExpressions: true
114+
}
115+
]
94116
}
95117
],
96118
invalid: [
@@ -187,6 +209,30 @@ class Test {
187209
column: 13
188210
}
189211
]
212+
},
213+
{
214+
filename: 'test.ts',
215+
code: `var arrowFn = () => 'test';`,
216+
options: [{ allowTypedFunctionExpressions: true }],
217+
errors: [
218+
{
219+
messageId: 'missingReturnType',
220+
line: 1,
221+
column: 15
222+
}
223+
]
224+
},
225+
{
226+
filename: 'test.ts',
227+
code: `var funcExpr = function() { return 'test'; };`,
228+
options: [{ allowTypedFunctionExpressions: true }],
229+
errors: [
230+
{
231+
messageId: 'missingReturnType',
232+
line: 1,
233+
column: 16
234+
}
235+
]
190236
}
191237
]
192238
});

0 commit comments

Comments
 (0)