Skip to content

Commit 293fb24

Browse files
fix(eslint-plugin): [no-unsafe-assignment] be more specific about error types (typescript-eslint#8304)
* fix: error assignment type issue * refactor: error assignment type * refactor: error assignment type * refactor: error assignment type * chore: resolve comments * fix: error type assignment tests * fix: error type assignment tests * chore: change yarn lock * fix: errot type assignments tests * chore: remove unnecessary error type check function * refactor: rename every error ocurrence to error typed * refactor: rename every error ocurrence to error typed * refactor: rename every error ocurrence to error typed * fix CI issues * fix CI issues * refactor: change create data from types function and add test data for test cases * refactor: remove unnecessary else
1 parent cb1720d commit 293fb24

File tree

3 files changed

+98
-23
lines changed

3 files changed

+98
-23
lines changed

packages/eslint-plugin/src/rules/no-unsafe-assignment.ts

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,18 @@ export default createRule({
3737
requiresTypeChecking: true,
3838
},
3939
messages: {
40-
anyAssignment: 'Unsafe assignment of an `any` value.',
40+
anyAssignment: 'Unsafe assignment of an {{sender}} value.',
4141
anyAssignmentThis: [
42-
'Unsafe assignment of an `any` value. `this` is typed as `any`.',
42+
'Unsafe assignment of an {{sender}} value. `this` is typed as `any`.',
4343
'You can try to fix this by turning on the `noImplicitThis` compiler option, or adding a `this` parameter to the function.',
4444
].join('\n'),
45-
unsafeArrayPattern: 'Unsafe array destructuring of an `any` array value.',
45+
unsafeArrayPattern:
46+
'Unsafe array destructuring of an {{sender}} array value.',
4647
unsafeArrayPatternFromTuple:
47-
'Unsafe array destructuring of a tuple element with an `any` value.',
48+
'Unsafe array destructuring of a tuple element with an {{sender}} value.',
4849
unsafeAssignment:
4950
'Unsafe assignment of type {{sender}} to a variable of type {{receiver}}.',
50-
unsafeArraySpread: 'Unsafe spread of an `any` value in an array.',
51+
unsafeArraySpread: 'Unsafe spread of an {{sender}} value in an array.',
5152
},
5253
schema: [],
5354
},
@@ -88,6 +89,7 @@ export default createRule({
8889
context.report({
8990
node: receiverNode,
9091
messageId: 'unsafeArrayPattern',
92+
data: createData(senderType),
9193
});
9294
return false;
9395
}
@@ -126,6 +128,7 @@ export default createRule({
126128
context.report({
127129
node: receiverElement,
128130
messageId: 'unsafeArrayPatternFromTuple',
131+
data: createData(senderType),
129132
});
130133
// we want to report on every invalid element in the tuple
131134
didReport = true;
@@ -212,6 +215,7 @@ export default createRule({
212215
context.report({
213216
node: receiverProperty.value,
214217
messageId: 'unsafeArrayPatternFromTuple',
218+
data: createData(senderType),
215219
});
216220
didReport = true;
217221
} else if (
@@ -275,7 +279,9 @@ export default createRule({
275279
context.report({
276280
node: reportingNode,
277281
messageId,
282+
data: createData(senderType),
278283
});
284+
279285
return true;
280286
}
281287

@@ -297,10 +303,7 @@ export default createRule({
297303
context.report({
298304
node: reportingNode,
299305
messageId: 'unsafeAssignment',
300-
data: {
301-
sender: checker.typeToString(sender),
302-
receiver: checker.typeToString(receiver),
303-
},
306+
data: createData(sender, receiver),
304307
});
305308
return true;
306309
}
@@ -315,6 +318,23 @@ export default createRule({
315318
ComparisonType.None;
316319
}
317320

321+
function createData(
322+
senderType: ts.Type,
323+
receiverType?: ts.Type,
324+
): Readonly<Record<string, unknown>> | undefined {
325+
if (receiverType) {
326+
return {
327+
sender: '`' + checker.typeToString(senderType) + '`',
328+
receiver: '`' + checker.typeToString(receiverType) + '`',
329+
};
330+
}
331+
return {
332+
sender: tsutils.isIntrinsicErrorType(senderType)
333+
? 'error typed'
334+
: '`any`',
335+
};
336+
}
337+
318338
return {
319339
'VariableDeclarator[init != null]'(
320340
node: TSESTree.VariableDeclarator,
@@ -383,6 +403,7 @@ export default createRule({
383403
context.report({
384404
node: node,
385405
messageId: 'unsafeArraySpread',
406+
data: createData(restType),
386407
});
387408
}
388409
},

packages/eslint-plugin/tests/docs-eslint-output-snapshots/no-unsafe-assignment.shot

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/eslint-plugin/tests/rules/no-unsafe-assignment.test.ts

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ declare function Foo(props: Props): never;
130130
},
131131
},
132132
},
133+
133134
{
134135
code: `
135136
declare function Foo(props: { a: string }): never;
@@ -195,7 +196,60 @@ class Foo {
195196
`,
196197
errors: [{ messageId: 'anyAssignment' }],
197198
},
199+
{
200+
code: `
201+
const [x] = spooky;
202+
`,
203+
errors: [
204+
{
205+
messageId: 'anyAssignment',
206+
data: { sender: 'error typed', receiver: 'error typed' },
207+
},
208+
],
209+
},
210+
{
211+
code: `
212+
const [[[x]]] = [spooky];
213+
`,
214+
errors: [
215+
{
216+
messageId: 'unsafeArrayPatternFromTuple',
217+
data: { sender: 'error typed', receiver: 'error typed' },
218+
},
219+
],
220+
},
221+
{
222+
code: `
223+
const {
224+
x: { y: z },
225+
} = { x: spooky };
226+
`,
227+
errors: [
228+
{
229+
messageId: 'unsafeArrayPatternFromTuple',
230+
data: { sender: 'error typed', receiver: 'error typed' },
231+
},
232+
{
233+
messageId: 'anyAssignment',
234+
data: { sender: 'error typed', receiver: 'error typed' },
235+
},
236+
],
237+
},
238+
{
239+
code: `
240+
let value: number;
198241
242+
value = spooky;
243+
`,
244+
errors: [
245+
{
246+
messageId: 'anyAssignment',
247+
data: {
248+
sender: 'error typed',
249+
},
250+
},
251+
],
252+
},
199253
{
200254
code: `
201255
const [x] = 1 as any;
@@ -215,8 +269,8 @@ const [x] = [] as any[];
215269
{
216270
messageId: 'unsafeAssignment',
217271
data: {
218-
sender: 'Set<any>',
219-
receiver: 'Set<string>',
272+
sender: '`Set<any>`',
273+
receiver: '`Set<string>`',
220274
},
221275
},
222276
],
@@ -227,8 +281,8 @@ const [x] = [] as any[];
227281
{
228282
messageId: 'unsafeAssignment',
229283
data: {
230-
sender: 'Map<string, any>',
231-
receiver: 'Map<string, string>',
284+
sender: '`Map<string, any>`',
285+
receiver: '`Map<string, string>`',
232286
},
233287
},
234288
],
@@ -239,8 +293,8 @@ const [x] = [] as any[];
239293
{
240294
messageId: 'unsafeAssignment',
241295
data: {
242-
sender: 'Set<any[]>',
243-
receiver: 'Set<string[]>',
296+
sender: '`Set<any[]>`',
297+
receiver: '`Set<string[]>`',
244298
},
245299
},
246300
],
@@ -251,8 +305,8 @@ const [x] = [] as any[];
251305
{
252306
messageId: 'unsafeAssignment',
253307
data: {
254-
sender: 'Set<Set<Set<any>>>',
255-
receiver: 'Set<Set<Set<string>>>',
308+
sender: '`Set<Set<Set<any>>>`',
309+
receiver: '`Set<Set<Set<string>>>`',
256310
},
257311
},
258312
],
@@ -327,8 +381,8 @@ const x = [...([] as any[])];
327381
column: 43,
328382
endColumn: 70,
329383
data: {
330-
sender: 'Set<Set<Set<any>>>',
331-
receiver: 'Set<Set<Set<string>>>',
384+
sender: '`Set<Set<Set<any>>>`',
385+
receiver: '`Set<Set<Set<string>>>`',
332386
},
333387
},
334388
],

0 commit comments

Comments
 (0)