Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(eslint-plugin): [no-unnec-type-assert] handle JSX attributes #1002

Merged
merged 11 commits into from Jan 13, 2020
1 change: 1 addition & 0 deletions packages/eslint-plugin/package.json
Expand Up @@ -50,6 +50,7 @@
"@types/json-schema": "^7.0.3",
"@types/marked": "^0.7.1",
"@types/prettier": "^1.18.2",
"@types/react": "^16.9.2",
armano2 marked this conversation as resolved.
Show resolved Hide resolved
"chalk": "^3.0.0",
"marked": "^0.7.0",
"prettier": "*",
Expand Down
@@ -1,6 +1,7 @@
import { TSESTree } from '@typescript-eslint/experimental-utils';
import {
isCallExpression,
isJsxExpression,
isNewExpression,
isObjectType,
isObjectFlagSet,
Expand Down Expand Up @@ -117,6 +118,8 @@ export default util.createRule<Options, MessageIds>({
return parent.type
? checker.getTypeFromTypeNode(parent.type)
: undefined;
} else if (isJsxExpression(parent)) {
return checker.getContextualType(parent);
} else if (
![ts.SyntaxKind.TemplateSpan, ts.SyntaxKind.JsxExpression].includes(
parent.kind,
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/tests/RuleTester.ts
Expand Up @@ -44,6 +44,7 @@ class RuleTester extends TSESLint.RuleTester {
): void {
const errorMessage = `Do not set the parser at the test level unless you want to use a parser other than ${parser}`;

// standardise the valid tests as objects
tests.valid = tests.valid.map(test => {
if (typeof test === 'string') {
return {
Expand Down
Empty file.
7 changes: 6 additions & 1 deletion packages/eslint-plugin/tests/fixtures/tsconfig.json
@@ -1,10 +1,15 @@
{
"compilerOptions": {
"jsx": "preserve",
"target": "es5",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"lib": ["es2015", "es2017", "esnext"],
"experimentalDecorators": true
}
},
"include": [
"file.ts",
"react.tsx"
]
}
@@ -1,3 +1,4 @@
import { clearCaches } from '@typescript-eslint/parser';
import path from 'path';
import rule from '../../src/rules/no-unnecessary-type-assertion';
import { RuleTester } from '../RuleTester';
Expand All @@ -12,6 +13,12 @@ const ruleTester = new RuleTester({
parser: '@typescript-eslint/parser',
});

// make sure each test is completely isolated
// there was some weird behaviour with the mixed ts/tsx test cases without this
afterEach(() => {
clearCaches();
armano2 marked this conversation as resolved.
Show resolved Hide resolved
});

ruleTester.run('no-unnecessary-type-assertion', rule, {
valid: [
'const foo = 3 as number;',
Expand Down Expand Up @@ -117,6 +124,19 @@ function testFunction(_param: string | null): void { /* noop */ }
const value = 'test' as string | null | undefined
testFunction(value!)
`,
// https://github.com/typescript-eslint/typescript-eslint/issues/982
{
code: `
const React = require("react");
armano2 marked this conversation as resolved.
Show resolved Hide resolved

function Test(props: {
id?: null | string | number;
}) {
return <div key={props.id!} />;
};
`,
filename: path.join(rootDir, 'react.tsx'),
Copy link
Member

@armano2 armano2 Jan 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filename for now has to be absolute when used with watch program (project)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to put this in the RuleTester?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no it should not be there, it should work correctly with relative paths
see #1439

},
],

invalid: [
Expand Down Expand Up @@ -327,5 +347,33 @@ class Mx {
},
],
},
// https://github.com/typescript-eslint/typescript-eslint/issues/982
{
code: `
const React = require("react");
armano2 marked this conversation as resolved.
Show resolved Hide resolved

function Test(props: {
id?: string | number;
}) {
return <div key={props.id!} />;
};
`,
output: `
const React = require("react");

function Test(props: {
id?: string | number;
}) {
return <div key={props.id} />;
};
`,
errors: [
{
messageId: 'contextuallyUnnecessary',
line: 7,
},
],
filename: path.join(rootDir, 'react.tsx'),
},
],
});
18 changes: 18 additions & 0 deletions yarn.lock
Expand Up @@ -1425,6 +1425,19 @@
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.18.3.tgz#64ff53329ce16139f17c3db9d3e0487199972cd8"
integrity sha512-48rnerQdcZ26odp+HOvDGX8IcUkYOCuMc2BodWYTe956MqkHlOGAG4oFQ83cjZ0a4GAgj7mb4GUClxYd2Hlodg==

"@types/prop-types@*":
version "15.7.2"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.2.tgz#0e58ae66773d7fd7c372a493aff740878ec9ceaa"
integrity sha512-f8JzJNWVhKtc9dg/dyDNfliTKNOJSLa7Oht/ElZdF/UbMUmAH3rLmAk3ODNjw0mZajDEgatA03tRjB4+Dp/tzA==

"@types/react@^16.9.2":
version "16.9.2"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.2.tgz#6d1765431a1ad1877979013906731aae373de268"
integrity sha512-jYP2LWwlh+FTqGd9v7ynUKZzjj98T8x7Yclz479QdRhHfuW9yQ+0jjnD31eXSXutmBpppj5PYNLYLRfnZJvcfg==
dependencies:
"@types/prop-types" "*"
csstype "^2.2.0"

"@types/semver@^6.0.1":
version "6.0.2"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.0.2.tgz#5e8b09f0e4af53034b1d0fb9977a277847836205"
Expand Down Expand Up @@ -2794,6 +2807,11 @@ cssstyle@^1.0.0:
dependencies:
cssom "0.3.x"

csstype@^2.2.0:
version "2.6.6"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.6.tgz#c34f8226a94bbb10c32cc0d714afdf942291fc41"
integrity sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg==

currently-unhandled@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
Expand Down