Skip to content

Commit 9d2bb6c

Browse files
committed
new copy
1 parent ad87d0d commit 9d2bb6c

File tree

1 file changed

+98
-33
lines changed

1 file changed

+98
-33
lines changed

eslint.config.ts

Lines changed: 98 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -270,25 +270,25 @@ export default defineConfig(
270270
//#endregion
271271

272272
{
273-
name: 'custom',
273+
name: "custom",
274274
plugins: {
275275
custom: {
276276
rules: {
277-
'no-arrow-parameter-types': {
277+
"no-arrow-parameter-types": {
278278
meta: {
279-
fixable: 'code',
279+
fixable: "code",
280280
hasSuggestions: true,
281-
type: 'suggestion',
282-
dialects: ['typescript'],
281+
type: "suggestion",
282+
dialects: ["typescript"],
283283
schema: [
284284
{
285-
type: 'object',
285+
type: "object",
286286
properties: {
287287
allowOptional: {
288-
type: 'boolean',
288+
type: "boolean",
289289
default: false,
290290
description:
291-
'Allow type annotations when the parameter is optional. Sometimes useful for overloaded functions.',
291+
"Allow type annotations when the parameter is optional. Sometimes useful for overloaded functions.",
292292
},
293293
},
294294
},
@@ -307,12 +307,12 @@ export default defineConfig(
307307
const paramsWithTypeAnnotation = node.params.filter(
308308
(
309309
// @ts-expect-error: will be inferred when moved into an official plugin
310-
param
311-
) => param.typeAnnotation !== undefined
310+
param,
311+
) => param.typeAnnotation !== undefined,
312312
);
313313

314314
const isCatchClause =
315-
node.parent.callee?.property?.name === 'catch';
315+
node.parent.callee?.property?.name === "catch";
316316

317317
if (paramsWithTypeAnnotation.length > 0 && !isCatchClause) {
318318
for (const param of paramsWithTypeAnnotation) {
@@ -323,51 +323,116 @@ export default defineConfig(
323323
context.report({
324324
node: param,
325325
message:
326-
'Arrow function parameters should not have type annotations. Instead the Object where the operation is used should be typed correctly.',
326+
"Arrow function parameters should not have type annotations. Instead the Object where the operation is used should be typed correctly.",
327327
fix(fixer) {
328328
if (param.optional) {
329329
return null;
330330
}
331331

332-
// TODO @Shinigami92 2025-06-16: Handle async arrow functions
333-
if (node.parent.type === 'VariableDeclarator') {
334-
const variableDeclaratorNode = node.parent;
332+
if (
333+
node.parent.type === "VariableDeclarator" &&
334+
!node.parent.id.typeAnnotation
335+
) {
336+
const variableDeclarationNode = node.parent;
335337

336-
return [
337-
// Remove ` =>`
338+
const isAsyncFunction: boolean = node.async;
339+
340+
const isBodyBlockStatement =
341+
node.body.type === "BlockStatement";
342+
343+
const isBodyJSXElement =
344+
node.body.type === "JSXElement";
345+
346+
const hasReturnType = node.returnType !== undefined;
347+
348+
const lastParam = node.params.at(-1);
349+
350+
const paramIdDifferentLine =
351+
lastParam.loc.start.line !==
352+
variableDeclarationNode.id.loc.end.line;
353+
354+
const paramBlockDifferentLine =
355+
lastParam.loc.end.line !==
356+
node.body.loc.start.line;
357+
358+
const behindClosingParenthesis = hasReturnType
359+
? (node.returnType.range[1] as number)
360+
: (lastParam.range[1] as number) + ")".length;
361+
362+
const fixes = [
363+
// Removes `=> `
338364
fixer.replaceTextRange(
339-
[node.body.range[0] - 3, node.body.range[0]],
340-
''
365+
[
366+
behindClosingParenthesis,
367+
node.body.range[0] as number,
368+
],
369+
!hasReturnType &&
370+
paramBlockDifferentLine &&
371+
paramIdDifferentLine
372+
? ")"
373+
: "",
341374
),
342-
// Remove ` = `
375+
// Removes ` = ` or ` = async `
343376
fixer.replaceTextRange(
344377
[
345-
variableDeclaratorNode.id.range[1],
346-
variableDeclaratorNode.init.range[0],
378+
variableDeclarationNode.id.range[1] as number,
379+
(variableDeclarationNode.init
380+
.range[0] as number) +
381+
(isAsyncFunction ? "async ".length : 0),
347382
],
348-
''
383+
"",
349384
),
350-
// Replace `const ` with `function `
385+
// Replaces `const ` with `function ` or `async function `
351386
fixer.replaceTextRange(
352387
[
353-
variableDeclaratorNode.parent.range[0],
354-
variableDeclaratorNode.range[0],
388+
variableDeclarationNode.parent
389+
.range[0] as number,
390+
variableDeclarationNode.range[0] as number,
355391
],
356-
'function '
392+
isAsyncFunction
393+
? "async function "
394+
: "function ",
357395
),
358396
];
397+
398+
// If the body is not a BlockStatement, we need to wrap it in curly braces
399+
if (!isBodyBlockStatement) {
400+
fixes.push(
401+
fixer.insertTextBefore(
402+
node.body,
403+
`{return ${isBodyJSXElement ? "(" : ""}`,
404+
),
405+
fixer.insertTextAfter(
406+
node.body,
407+
`${isBodyJSXElement ? ")" : ""}}`,
408+
),
409+
);
410+
411+
if (isBodyJSXElement) {
412+
fixes.push(
413+
fixer.removeRange([
414+
node.body.range[1] as number,
415+
node.range[1] as number,
416+
]),
417+
);
418+
}
419+
}
420+
421+
return fixes;
359422
}
360423

361-
return fixer.removeRange(param.typeAnnotation.range);
424+
return fixer.removeRange(
425+
param.typeAnnotation.range as [number, number],
426+
);
362427
},
363428
suggest: [
364429
{
365-
desc: 'Remove type annotation',
430+
desc: "Remove type annotation",
366431
fix(fixer) {
367432
if (param.optional) {
368433
return fixer.removeRange([
369-
param.typeAnnotation.range[0] - 1, // Remove the `?` before the type annotation
370-
param.typeAnnotation.range[1],
434+
(param.typeAnnotation.range[0] as number) - 1, // Remove the `?` before the type annotation
435+
param.typeAnnotation.range[1] as number,
371436
]);
372437
}
373438

@@ -386,7 +451,7 @@ export default defineConfig(
386451
},
387452
},
388453
rules: {
389-
'custom/no-arrow-parameter-types': ['error', { allowOptional: true }],
454+
"custom/no-arrow-parameter-types": ["error", { allowOptional: true }],
390455
},
391-
}
456+
},
392457
);

0 commit comments

Comments
 (0)