Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Tadhg McDonald-Jensen committed Sep 21, 2020
2 parents 2f126ae + 53a3cbc commit 01d395d
Show file tree
Hide file tree
Showing 10 changed files with 326 additions and 74 deletions.
32 changes: 32 additions & 0 deletions docs/getting-started/linting/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- [How can I ban `<specific language feature>`?](#how-can-i-ban-specific-language-feature)
- [Why don't I see TypeScript errors in my ESLint output?](#why-dont-i-see-typescript-errors-in-my-eslint-output)
- [I get errors from the `no-undef` rule about global variables not being defined, even though there are no TypeScript errors](#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors)
- [How do I check to see what versions are installed?](#how-do-i-check-to-see-what-versions-are-installed)
- [My linting feels really slow](#my-linting-feels-really-slow)

---
Expand Down Expand Up @@ -188,6 +189,37 @@ The `no-undef` lint rule does not use TypeScript to determine the global variabl

You can [manually define the set of allowed `globals` in your ESLint config](https://eslint.org/docs/user-guide/configuring#specifying-globals), and/or you can use one of the [pre-defined environment (`env`) configurations](https://eslint.org/docs/user-guide/configuring#specifying-environments).

As of our v4.0.0 release, this also applies to types. If you use global types from a 3rd party package (i.e. anything from an `@types` package), then you will have to configure ESLint appropriately to define these global types. For example; the `JSX` namespace from `@types/react` is a global 3rd party type that you must define in your ESLint config.

We strongly recommend that you do not use the `no-undef` lint rule on TypeScript projects. The checks it provides are already provided by TypeScript without the need for configuration - TypeScript just does this significantly better.

<br />
<br />
<br />

---

<br />
<br />
<br />

## How do I check to see what versions are installed?

If you have multiple versions of our tooling, it can cause various bugs for you. This is because ESLint may load a different version each run depending on how you run it - leading to inconsistent lint results.

Installing our tooling in the root of your project does not mean that only one version is installed. One or more of your dependencies may have its own dependency on our tooling, meaning `npm`/`yarn` will additionally install that version for use by that package. For example, `react-scripts` (part of `create-react-app`) has a dependency on our tooling.

You can check what versions are installed in your project using the following commands:

```bash
$ npm list @typescript-eslint/eslint-plugin @typescript-eslint/parser
$ yarn list @typescript-eslint/eslint-plugin @typescript-eslint/parser
```

If you see more than one version installed, then you will have to either use [yarn resolutions](https://classic.yarnpkg.com/en/docs/selective-version-resolutions/) to force a single version, or you will have to downgrade your root versions to match the dependency versions.

**The best course of action in this case is to wait until your dependency releases a new version with support for our latest versions.**

<br />
<br />
<br />
Expand Down
134 changes: 67 additions & 67 deletions packages/eslint-plugin/ROADMAP.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/eslint-plugin/docs/rules/no-redeclare.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ See [`eslint/no-redeclare` options](https://eslint.org/docs/rules/no-redeclare#o
This rule adds the following options:

```ts
interface Options extends BaseNoShadowOptions {
interface Options extends BaseNoRedeclareOptions {
ignoreDeclarationMerge?: boolean;
}

const defaultOptions: Options = {
...baseNoShadowDefaultOptions,
...baseNoRedeclareDefaultOptions,
ignoreDeclarationMerge: true,
};
```
Expand Down
6 changes: 3 additions & 3 deletions packages/eslint-plugin/docs/rules/no-unsafe-member-access.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ Examples of **correct** code for this rule:
```ts
declare const properlyTyped: { prop: { a: string } };

nestedAny.prop.a;
nestedAny.prop['a'];
properlyTyped.prop.a;
properlyTyped.prop['a'];

const key = 'a';
nestedAny.prop[key];
properlyTyped.prop[key];

const arr = [1, 2, 3];
arr[1];
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/src/rules/naming-convention.ts
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ export default util.createRule<Options, MessageIds>({

// #region property

'Property[computed = false][kind = "init"][value.type != "ArrowFunctionExpression"][value.type != "FunctionExpression"][value.type != "TSEmptyBodyFunctionExpression"]'(
':not(ObjectPattern) > Property[computed = false][kind = "init"][value.type != "ArrowFunctionExpression"][value.type != "FunctionExpression"][value.type != "TSEmptyBodyFunctionExpression"]'(
node: TSESTree.PropertyNonComputedName,
): void {
const modifiers = new Set<Modifiers>([Modifiers.public]);
Expand Down
34 changes: 34 additions & 0 deletions packages/eslint-plugin/tests/rules/naming-convention.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,20 @@ ruleTester.run('naming-convention', rule, {
},
],
},
{
code: `
class SomeClass {
static OtherConstant = 'hello';
}
export const { OtherConstant: otherConstant } = SomeClass;
`,
parserOptions,
options: [
{ selector: 'property', format: ['PascalCase'] },
{ selector: 'variable', format: ['camelCase'] },
],
},
],
invalid: [
{
Expand Down Expand Up @@ -1282,5 +1296,25 @@ ruleTester.run('naming-convention', rule, {
],
errors: [{ messageId: 'doesNotMatchFormatTrimmed' }],
},
{
code: `
class SomeClass {
static otherConstant = 'hello';
}
export const { otherConstant } = SomeClass;
`,
parserOptions,
options: [
{ selector: 'property', format: ['PascalCase'] },
{ selector: 'variable', format: ['camelCase'] },
],
errors: [
{
line: 3,
messageId: 'doesNotMatchFormat',
},
],
},
],
});
8 changes: 8 additions & 0 deletions packages/eslint-plugin/tests/rules/no-shadow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ const ruleTester = new RuleTester({

ruleTester.run('no-shadow TS tests', rule, {
valid: [
// nested conditional types
`
export type ArrayInput<Func> = Func extends (arg0: Array<infer T>) => any
? T[]
: Func extends (...args: infer T) => any
? T
: never;
`,
`
function foo() {
var Object = 0;
Expand Down
5 changes: 4 additions & 1 deletion packages/scope-manager/src/referencer/TypeVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,12 @@ class TypeVisitor extends Visitor {
// which are only accessible from inside the conditional parameter
this.#referencer.scopeManager.nestConditionalTypeScope(node);

this.visitChildren(node);
// type parameters inferred in the condition clause are not accessible within the false branch
this.visitChildren(node, ['falseType']);

this.#referencer.close(node);

this.visit(node.falseType);
}

protected TSConstructorType(node: TSESTree.TSConstructorType): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type Test<T> = T extends Array<infer U>
? U
: T extends Set<infer U>
? U
: never;
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`type-declaration conditional-nested 1`] = `
ScopeManager {
variables: Array [
ImplicitGlobalConstTypeVariable,
Variable$2 {
defs: Array [
TypeDefinition$1 {
name: Identifier<"Test">,
node: TSTypeAliasDeclaration$1,
},
],
name: "Test",
references: Array [],
isValueVariable: false,
isTypeVariable: true,
},
Variable$3 {
defs: Array [
TypeDefinition$2 {
name: Identifier<"T">,
node: TSTypeParameter$2,
},
],
name: "T",
references: Array [
Reference$1 {
identifier: Identifier<"T">,
isRead: true,
isTypeReference: true,
isValueReference: false,
isWrite: false,
resolved: Variable$3,
},
Reference$4 {
identifier: Identifier<"T">,
isRead: true,
isTypeReference: true,
isValueReference: false,
isWrite: false,
resolved: Variable$3,
},
],
isValueVariable: false,
isTypeVariable: true,
},
Variable$4 {
defs: Array [
TypeDefinition$3 {
name: Identifier<"U">,
node: TSTypeParameter$3,
},
],
name: "U",
references: Array [
Reference$3 {
identifier: Identifier<"U">,
isRead: true,
isTypeReference: true,
isValueReference: false,
isWrite: false,
resolved: Variable$4,
},
],
isValueVariable: false,
isTypeVariable: true,
},
Variable$5 {
defs: Array [
TypeDefinition$4 {
name: Identifier<"U">,
node: TSTypeParameter$4,
},
],
name: "U",
references: Array [
Reference$6 {
identifier: Identifier<"U">,
isRead: true,
isTypeReference: true,
isValueReference: false,
isWrite: false,
resolved: Variable$5,
},
],
isValueVariable: false,
isTypeVariable: true,
},
],
scopes: Array [
GlobalScope$1 {
block: Program$5,
isStrict: false,
references: Array [],
set: Map {
"const" => ImplicitGlobalConstTypeVariable,
"Test" => Variable$2,
},
type: "global",
upper: null,
variables: Array [
ImplicitGlobalConstTypeVariable,
Variable$2,
],
},
TypeScope$2 {
block: TSTypeAliasDeclaration$1,
isStrict: true,
references: Array [],
set: Map {
"T" => Variable$3,
},
type: "type",
upper: GlobalScope$1,
variables: Array [
Variable$3,
],
},
ConditionalTypeScope$3 {
block: TSConditionalType$6,
isStrict: true,
references: Array [
Reference$1,
Reference$2 {
identifier: Identifier<"Array">,
isRead: true,
isTypeReference: true,
isValueReference: false,
isWrite: false,
resolved: null,
},
Reference$3,
],
set: Map {
"U" => Variable$4,
},
type: "conditionalType",
upper: TypeScope$2,
variables: Array [
Variable$4,
],
},
ConditionalTypeScope$4 {
block: TSConditionalType$7,
isStrict: true,
references: Array [
Reference$4,
Reference$5 {
identifier: Identifier<"Set">,
isRead: true,
isTypeReference: true,
isValueReference: false,
isWrite: false,
resolved: null,
},
Reference$6,
],
set: Map {
"U" => Variable$5,
},
type: "conditionalType",
upper: TypeScope$2,
variables: Array [
Variable$5,
],
},
],
}
`;

0 comments on commit 01d395d

Please sign in to comment.