Skip to content

Commit 55a58ff

Browse files
authored
feat(eslint-plugin): [no-unsafe-call] support tagged templates (#1680)
1 parent 144345c commit 55a58ff

File tree

3 files changed

+41
-10
lines changed

3 files changed

+41
-10
lines changed

Diff for: packages/eslint-plugin/docs/rules/no-unsafe-call.md

+5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ nestedAny.prop['a']();
2121

2222
new anyVar();
2323
new nestedAny.prop();
24+
25+
anyVar`foo`;
26+
nestedAny.prop`foo`;
2427
```
2528

2629
Examples of **correct** code for this rule:
@@ -33,6 +36,8 @@ nestedAny.prop.a();
3336
(() => {})();
3437

3538
new Map();
39+
40+
String.raw`foo`;
3641
```
3742

3843
## Related to

Diff for: packages/eslint-plugin/src/rules/no-unsafe-call.ts

+15-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { TSESTree } from '@typescript-eslint/experimental-utils';
22
import * as util from '../util';
33

4-
type MessageIds = 'unsafeCall' | 'unsafeNew';
4+
type MessageIds = 'unsafeCall' | 'unsafeNew' | 'unsafeTemplateTag';
55

66
export default util.createRule<[], MessageIds>({
77
name: 'no-unsafe-call',
@@ -16,6 +16,7 @@ export default util.createRule<[], MessageIds>({
1616
messages: {
1717
unsafeCall: 'Unsafe call of an any typed value',
1818
unsafeNew: 'Unsafe construction of an any type value',
19+
unsafeTemplateTag: 'Unsafe any typed template tag',
1920
},
2021
schema: [],
2122
},
@@ -25,14 +26,11 @@ export default util.createRule<[], MessageIds>({
2526
const checker = program.getTypeChecker();
2627

2728
function checkCall(
28-
node:
29-
| TSESTree.CallExpression
30-
| TSESTree.OptionalCallExpression
31-
| TSESTree.NewExpression,
32-
reportingNode: TSESTree.Expression = node.callee,
33-
messageId: MessageIds = 'unsafeCall',
29+
node: TSESTree.Node,
30+
reportingNode: TSESTree.Node,
31+
messageId: MessageIds,
3432
): void {
35-
const tsNode = esTreeNodeToTSNodeMap.get(node.callee);
33+
const tsNode = esTreeNodeToTSNodeMap.get(node);
3634
const type = checker.getTypeAtLocation(tsNode);
3735
if (util.isTypeAnyType(type)) {
3836
context.report({
@@ -43,9 +41,16 @@ export default util.createRule<[], MessageIds>({
4341
}
4442

4543
return {
46-
'CallExpression, OptionalCallExpression': checkCall,
44+
'CallExpression, OptionalCallExpression'(
45+
node: TSESTree.CallExpression | TSESTree.OptionalCallExpression,
46+
): void {
47+
checkCall(node.callee, node.callee, 'unsafeCall');
48+
},
4749
NewExpression(node): void {
48-
checkCall(node, node, 'unsafeNew');
50+
checkCall(node.callee, node, 'unsafeNew');
51+
},
52+
'TaggedTemplateExpression > *.tag'(node: TSESTree.Node): void {
53+
checkCall(node, node, 'unsafeTemplateTag');
4954
},
5055
};
5156
},

Diff for: packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts

+21
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ ruleTester.run('no-unsafe-call', rule, {
1919
'function foo(x?: { a: () => void }) { x?.a() }',
2020
'function foo(x: { a?: () => void }) { x.a?.() }',
2121
'new Map()',
22+
'String.raw`foo`',
2223
],
2324
invalid: [
2425
...batchedSingleLineTests({
@@ -102,5 +103,25 @@ function foo(x: { a: any }) { new x.a() }
102103
},
103104
],
104105
}),
106+
...batchedSingleLineTests({
107+
code: `
108+
function foo(x: any) { x\`foo\` }
109+
function foo(x: { tag: any }) { x.tag\`foo\` }
110+
`,
111+
errors: [
112+
{
113+
messageId: 'unsafeTemplateTag',
114+
line: 2,
115+
column: 24,
116+
endColumn: 25,
117+
},
118+
{
119+
messageId: 'unsafeTemplateTag',
120+
line: 3,
121+
column: 33,
122+
endColumn: 38,
123+
},
124+
],
125+
}),
105126
],
106127
});

0 commit comments

Comments
 (0)