Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(eslint-plugin): add rule
prefer-ts-expect-error
(#1705)
- Loading branch information
Showing
7 changed files
with
192 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
packages/eslint-plugin/docs/rules/prefer-ts-expect-error.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Recommends using `// @ts-expect-error` over `// @ts-ignore` (`prefer-ts-expect-error`) | ||
|
||
TypeScript allows you to suppress all errors on a line by placing a single-line comment starting with `@ts-ignore` immediately before the erroring line. | ||
While powerful, there is no way to know if a `@ts-ignore` is actually suppressing an error without manually investigating what happens when the `@ts-ignore` is removed. | ||
|
||
This means its easy for `@ts-ignore`s to be forgotten about, and remain in code even after the error they were suppressing is fixed. | ||
This is dangerous, as if a new error arises on that line it'll be suppressed by the forgotten about `@ts-ignore`, and so be missed. | ||
|
||
To address this, TS3.9 ships with a new single-line comment directive: `// @ts-expect-error`. | ||
|
||
This directive operates in the same manner as `@ts-ignore`, but will error if the line it's meant to be suppressing doesn't actually contain an error, making it a lot safer. | ||
|
||
## Rule Details | ||
|
||
This rule looks for usages of `@ts-ignore`, and flags them to be replaced with `@ts-expect-error`. | ||
|
||
Examples of **incorrect** code for this rule: | ||
|
||
```ts | ||
// @ts-ignore | ||
const str: string = 1; | ||
|
||
const isOptionEnabled = (key: string): boolean => { | ||
// @ts-ignore: if key isn't in globalOptions it'll be undefined which is false | ||
return !!globalOptions[key]; | ||
}; | ||
``` | ||
|
||
Examples of **correct** code for this rule: | ||
|
||
```ts | ||
// @ts-expect-error | ||
const str: string = 1; | ||
|
||
const isOptionEnabled = (key: string): boolean => { | ||
// @ts-expect-error: if key isn't in globalOptions it'll be undefined which is false | ||
return !!globalOptions[key]; | ||
}; | ||
``` | ||
|
||
## When Not To Use It | ||
|
||
If you are not using TypeScript 3.9 (or greater), then you will not be able to use this rule, as the directive is not supported | ||
|
||
## Further Reading | ||
|
||
- [Original Implementing PR](https://github.com/microsoft/TypeScript/pull/36014) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
packages/eslint-plugin/src/rules/prefer-ts-expect-error.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { AST_TOKEN_TYPES } from '@typescript-eslint/experimental-utils'; | ||
import * as util from '../util'; | ||
|
||
type MessageIds = 'preferExpectErrorComment'; | ||
|
||
export default util.createRule<[], MessageIds>({ | ||
name: 'prefer-ts-expect-error', | ||
meta: { | ||
type: 'problem', | ||
docs: { | ||
description: | ||
'Recommends using `// @ts-expect-error` over `// @ts-ignore`', | ||
category: 'Best Practices', | ||
recommended: false, | ||
}, | ||
fixable: 'code', | ||
messages: { | ||
preferExpectErrorComment: | ||
'Use "// @ts-expect-error" to ensure an error is actually being suppressed.', | ||
}, | ||
schema: [], | ||
}, | ||
defaultOptions: [], | ||
create(context) { | ||
const tsIgnoreRegExp = /^\/*\s*@ts-ignore/; | ||
const sourceCode = context.getSourceCode(); | ||
|
||
return { | ||
Program(): void { | ||
const comments = sourceCode.getAllComments(); | ||
|
||
comments.forEach(comment => { | ||
if (comment.type !== AST_TOKEN_TYPES.Line) { | ||
return; | ||
} | ||
|
||
if (tsIgnoreRegExp.test(comment.value)) { | ||
context.report({ | ||
node: comment, | ||
messageId: 'preferExpectErrorComment', | ||
fix: fixer => | ||
fixer.replaceText( | ||
comment, | ||
`//${comment.value.replace( | ||
'@ts-ignore', | ||
'@ts-expect-error', | ||
)}`, | ||
), | ||
}); | ||
} | ||
}); | ||
}, | ||
}; | ||
}, | ||
}); |
85 changes: 85 additions & 0 deletions
85
packages/eslint-plugin/tests/rules/prefer-ts-expect-error.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import rule from '../../src/rules/prefer-ts-expect-error'; | ||
import { RuleTester } from '../RuleTester'; | ||
|
||
const ruleTester = new RuleTester({ | ||
parser: '@typescript-eslint/parser', | ||
}); | ||
|
||
ruleTester.run('prefer-ts-expect-error', rule, { | ||
valid: [ | ||
'// @ts-nocheck', | ||
'// @ts-check', | ||
'// just a comment containing @ts-ignore somewhere', | ||
'/* @ts-ignore */', | ||
'/** @ts-ignore */', | ||
` | ||
/* | ||
// @ts-ignore in a block | ||
*/ | ||
`, | ||
'// @ts-expect-error', | ||
` | ||
if (false) { | ||
// @ts-expect-error: Unreachable code error | ||
console.log('hello'); | ||
} | ||
`, | ||
], | ||
invalid: [ | ||
{ | ||
code: '// @ts-ignore', | ||
output: '// @ts-expect-error', | ||
errors: [ | ||
{ | ||
messageId: 'preferExpectErrorComment', | ||
line: 1, | ||
column: 1, | ||
}, | ||
], | ||
}, | ||
{ | ||
code: '// @ts-ignore: Suppress next line', | ||
output: '// @ts-expect-error: Suppress next line', | ||
|
||
errors: [ | ||
{ | ||
messageId: 'preferExpectErrorComment', | ||
line: 1, | ||
column: 1, | ||
}, | ||
], | ||
}, | ||
{ | ||
code: '/////@ts-ignore: Suppress next line', | ||
output: '/////@ts-expect-error: Suppress next line', | ||
errors: [ | ||
{ | ||
messageId: 'preferExpectErrorComment', | ||
line: 1, | ||
column: 1, | ||
}, | ||
], | ||
}, | ||
{ | ||
code: ` | ||
if (false) { | ||
// @ts-ignore: Unreachable code error | ||
console.log('hello'); | ||
} | ||
`, | ||
output: ` | ||
if (false) { | ||
// @ts-expect-error: Unreachable code error | ||
console.log('hello'); | ||
} | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'preferExpectErrorComment', | ||
line: 3, | ||
column: 3, | ||
}, | ||
], | ||
}, | ||
], | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters