Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit df410a1

Browse files
committed
fix(eslint-plugin): handle jsx attributes
1 parent cf1cba3 commit df410a1

File tree

2 files changed

+42
-31
lines changed

2 files changed

+42
-31
lines changed

packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { TSESTree } from '@typescript-eslint/experimental-utils';
22
import {
33
isCallExpression,
4+
isJsxExpression,
45
isNewExpression,
56
isObjectType,
67
isObjectFlagSet,
@@ -117,6 +118,8 @@ export default util.createRule<Options, MessageIds>({
117118
return parent.type
118119
? checker.getTypeFromTypeNode(parent.type)
119120
: undefined;
121+
} else if (isJsxExpression(parent)) {
122+
return checker.getContextualType(parent);
120123
} else if (
121124
![ts.SyntaxKind.TemplateSpan, ts.SyntaxKind.JsxExpression].includes(
122125
parent.kind,
@@ -216,10 +219,17 @@ export default util.createRule<Options, MessageIds>({
216219
contextualType,
217220
ts.TypeFlags.Null,
218221
);
219-
if (
220-
(typeIncludesUndefined && contextualTypeIncludesUndefined) ||
221-
(typeIncludesNull && contextualTypeIncludesNull)
222-
) {
222+
223+
// make sure that the parent accepts the same types
224+
// i.e. assigning `string | null | undefined` to `string | undefined` is invalid
225+
const isValidUndefined = typeIncludesUndefined
226+
? contextualTypeIncludesUndefined
227+
: true;
228+
const isValidNull = typeIncludesNull
229+
? contextualTypeIncludesNull
230+
: true;
231+
232+
if (isValidUndefined && isValidNull) {
223233
context.report({
224234
node,
225235
messageId: 'contextuallyUnnecessary',

packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -117,33 +117,6 @@ function Test(props: {
117117
`,
118118
filename: 'react.tsx',
119119
},
120-
{
121-
code: `
122-
const React = require("react");
123-
124-
export namespace appTest {
125-
type ArtificialKey = string | number;
126-
interface ReactAttributeArtificial {
127-
key?: ArtificialKey;
128-
}
129-
type Data = {
130-
id?: null | string | number;
131-
};
132-
133-
export const Test = (props: Data) => {
134-
return ChildFn({ key: props.id! });
135-
};
136-
137-
export const Test2 = (props: Data) => {
138-
return <ChildCmp key={props.id} />;
139-
};
140-
141-
const ChildFn = (props: ReactAttributeArtificial) => "Hello";
142-
const ChildCmp = () => <div>Hello</div>;
143-
}
144-
`,
145-
filename: 'react.tsx',
146-
},
147120
],
148121

149122
invalid: [
@@ -354,5 +327,33 @@ class Mx {
354327
},
355328
],
356329
},
330+
// https://github.com/typescript-eslint/typescript-eslint/issues/982
331+
{
332+
code: `
333+
const React = require("react");
334+
335+
function Test(props: {
336+
id?: string | number;
337+
}) {
338+
return <div key={props.id!} />;
339+
};
340+
`,
341+
output: `
342+
const React = require("react");
343+
344+
function Test(props: {
345+
id?: string | number;
346+
}) {
347+
return <div key={props.id} />;
348+
};
349+
`,
350+
errors: [
351+
{
352+
messageId: 'contextuallyUnnecessary',
353+
line: 7,
354+
},
355+
],
356+
filename: 'react.tsx',
357+
},
357358
],
358359
});

0 commit comments

Comments
 (0)