Skip to content

Commit 14c6f80

Browse files
ZzzenJamesHenry
authored andcommitted
feat: [no-unnecessary-type-assertion] allow as const arrow functions (typescript-eslint#876)
1 parent b006667 commit 14c6f80

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ type Options = [
99
allowExpressions?: boolean;
1010
allowTypedFunctionExpressions?: boolean;
1111
allowHigherOrderFunctions?: boolean;
12+
allowDirectConstAssertionInArrowFunctions?: boolean;
1213
},
1314
];
1415
type MessageIds = 'missingReturnType';
@@ -39,6 +40,9 @@ export default util.createRule<Options, MessageIds>({
3940
allowHigherOrderFunctions: {
4041
type: 'boolean',
4142
},
43+
allowDirectConstAssertionInArrowFunctions: {
44+
type: 'boolean',
45+
},
4246
},
4347
additionalProperties: false,
4448
},
@@ -49,6 +53,7 @@ export default util.createRule<Options, MessageIds>({
4953
allowExpressions: false,
5054
allowTypedFunctionExpressions: true,
5155
allowHigherOrderFunctions: true,
56+
allowDirectConstAssertionInArrowFunctions: true,
5257
},
5358
],
5459
create(context, [options]) {
@@ -203,6 +208,30 @@ export default util.createRule<Options, MessageIds>({
203208
);
204209
}
205210

211+
/**
212+
* Checks if a function belongs to:
213+
* `() => ({ action: 'xxx' }) as const`
214+
*/
215+
function returnsConstAssertionDirectly(
216+
node: TSESTree.ArrowFunctionExpression,
217+
): boolean {
218+
const { body } = node;
219+
if (body.type === AST_NODE_TYPES.TSAsExpression) {
220+
const { typeAnnotation } = body;
221+
if (typeAnnotation.type === AST_NODE_TYPES.TSTypeReference) {
222+
const { typeName } = typeAnnotation;
223+
if (
224+
typeName.type === AST_NODE_TYPES.Identifier &&
225+
typeName.name === 'const'
226+
) {
227+
return true;
228+
}
229+
}
230+
}
231+
232+
return false;
233+
}
234+
206235
/**
207236
* Checks if a function declaration/expression has a return type.
208237
*/
@@ -263,6 +292,15 @@ export default util.createRule<Options, MessageIds>({
263292
}
264293
}
265294

295+
// https://github.com/typescript-eslint/typescript-eslint/issues/653
296+
if (
297+
node.type === AST_NODE_TYPES.ArrowFunctionExpression &&
298+
options.allowDirectConstAssertionInArrowFunctions &&
299+
returnsConstAssertionDirectly(node)
300+
) {
301+
return;
302+
}
303+
266304
checkFunctionReturnType(node);
267305
}
268306

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,20 @@ foo({
308308
},
309309
],
310310
},
311+
{
312+
filename: 'test.ts',
313+
code: `
314+
const func = (value: number) => (({ type: "X", value }) as const);
315+
const func = (value: number) => ({ type: "X", value } as const);
316+
const func = (value: number) => (x as const);
317+
const func = (value: number) => x as const;
318+
`,
319+
options: [
320+
{
321+
allowDirectConstAssertionInArrowFunctions: true,
322+
},
323+
],
324+
},
311325
],
312326
invalid: [
313327
{
@@ -749,5 +763,47 @@ foo({
749763
},
750764
],
751765
},
766+
{
767+
filename: 'test.ts',
768+
code: `
769+
const func = (value: number) => ({ type: "X", value } as any);
770+
const func = (value: number) => ({ type: "X", value } as Action);
771+
`,
772+
options: [
773+
{
774+
allowDirectConstAssertionInArrowFunctions: true,
775+
},
776+
],
777+
errors: [
778+
{
779+
messageId: 'missingReturnType',
780+
line: 2,
781+
column: 14,
782+
},
783+
{
784+
messageId: 'missingReturnType',
785+
line: 3,
786+
column: 14,
787+
},
788+
],
789+
},
790+
{
791+
filename: 'test.ts',
792+
code: `
793+
const func = (value: number) => ({ type: "X", value } as const);
794+
`,
795+
options: [
796+
{
797+
allowDirectConstAssertionInArrowFunctions: false,
798+
},
799+
],
800+
errors: [
801+
{
802+
messageId: 'missingReturnType',
803+
line: 2,
804+
column: 14,
805+
},
806+
],
807+
},
752808
],
753809
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy