Skip to content

Commit

Permalink
feat(eslint-plugin): [consistent-type-assertions] autofix angle brack…
Browse files Browse the repository at this point in the history
…et assertions to as (#6641)

* Autofix angle bracket assertions to as

* Include parentheses
  • Loading branch information
NotWoods committed Mar 21, 2023
1 parent aa537e5 commit ad8ea64
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 3 deletions.
38 changes: 37 additions & 1 deletion packages/eslint-plugin/src/rules/consistent-type-assertions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { TSESTree } from '@typescript-eslint/utils';
import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
import { AST_NODE_TYPES } from '@typescript-eslint/utils';

import * as util from '../util';
Expand All @@ -23,6 +23,7 @@ export default util.createRule<Options, MessageIds>({
name: 'consistent-type-assertions',
meta: {
type: 'suggestion',
fixable: 'code',
docs: {
description: 'Enforce consistent usage of type assertions',
recommended: 'strict',
Expand Down Expand Up @@ -83,6 +84,28 @@ export default util.createRule<Options, MessageIds>({
);
}

function getTextWithParentheses(node: TSESTree.Node): string {
// Capture parentheses before and after the node
let beforeCount = 0;
let afterCount = 0;

if (util.isParenthesized(node, sourceCode)) {
const bodyOpeningParen = sourceCode.getTokenBefore(
node,
util.isOpeningParenToken,
)!;
const bodyClosingParen = sourceCode.getTokenAfter(
node,
util.isClosingParenToken,
)!;

beforeCount = node.range[0] - bodyOpeningParen.range[0];
afterCount = bodyClosingParen.range[1] - node.range[1];
}

return sourceCode.getText(node, beforeCount, afterCount);
}

function reportIncorrectAssertionType(
node: TSESTree.TSTypeAssertion | TSESTree.TSAsExpression,
): void {
Expand All @@ -100,6 +123,19 @@ export default util.createRule<Options, MessageIds>({
messageId !== 'never'
? { cast: sourceCode.getText(node.typeAnnotation) }
: {},
fix:
messageId === 'as'
? (fixer): TSESLint.RuleFix[] => [
fixer.replaceText(
node,
getTextWithParentheses(node.expression),
),
fixer.insertTextAfter(
node,
` as ${getTextWithParentheses(node.typeAnnotation)}`,
),
]
: undefined,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ const ANGLE_BRACKET_TESTS_EXCEPT_CONST_CASE = `
const x = <Foo>new Generic<int>();
const x = <A>b;
const x = <readonly number[]>[1];
const x = <a | b>('string');`;
const x = <a | b>('string');
const x = <A>!'string';
const x = <A>a + b;
const x = <(A)>a + (b);
const x = <Foo>(new Generic<string>());
const x = (new (<Foo>Generic<string>)());`;

const ANGLE_BRACKET_TESTS = `${ANGLE_BRACKET_TESTS_EXCEPT_CONST_CASE}
const x = <const>{ key: 'value' };
Expand All @@ -19,7 +24,12 @@ const AS_TESTS_EXCEPT_CONST_CASE = `
const x = new Generic<int>() as Foo;
const x = b as A;
const x = [1] as readonly number[];
const x = ('string') as a | b;`;
const x = ('string') as a | b;
const x = !'string' as A;
const x = a as A + b;
const x = a as (A) + (b);
const x = (new Generic<string>()) as Foo;
const x = (new (Generic<string> as Foo)());`;

const AS_TESTS = `${AS_TESTS_EXCEPT_CONST_CASE}
const x = { key: 'value' } as const;
Expand Down Expand Up @@ -164,6 +174,26 @@ ruleTester.run('consistent-type-assertions', rule, {
messageId: 'angle-bracket',
line: 6,
},
{
messageId: 'angle-bracket',
line: 7,
},
{
messageId: 'angle-bracket',
line: 8,
},
{
messageId: 'angle-bracket',
line: 9,
},
{
messageId: 'angle-bracket',
line: 10,
},
{
messageId: 'angle-bracket',
line: 11,
},
],
}),
...batchedSingleLineTests({
Expand Down Expand Up @@ -194,7 +224,28 @@ ruleTester.run('consistent-type-assertions', rule, {
messageId: 'as',
line: 6,
},
{
messageId: 'as',
line: 7,
},
{
messageId: 'as',
line: 8,
},
{
messageId: 'as',
line: 9,
},
{
messageId: 'as',
line: 10,
},
{
messageId: 'as',
line: 11,
},
],
output: AS_TESTS,
}),
...batchedSingleLineTests({
code: AS_TESTS_EXCEPT_CONST_CASE,
Expand Down Expand Up @@ -224,6 +275,22 @@ ruleTester.run('consistent-type-assertions', rule, {
messageId: 'never',
line: 6,
},
{
messageId: 'never',
line: 7,
},
{
messageId: 'never',
line: 8,
},
{
messageId: 'never',
line: 9,
},
{
messageId: 'never',
line: 10,
},
],
}),
...batchedSingleLineTests({
Expand Down Expand Up @@ -254,6 +321,22 @@ ruleTester.run('consistent-type-assertions', rule, {
messageId: 'never',
line: 6,
},
{
messageId: 'never',
line: 7,
},
{
messageId: 'never',
line: 8,
},
{
messageId: 'never',
line: 9,
},
{
messageId: 'never',
line: 10,
},
],
}),
...batchedSingleLineTests({
Expand Down

0 comments on commit ad8ea64

Please sign in to comment.