diff --git a/CHANGELOG.md b/CHANGELOG.md index ef30e7d79104..24b66c8e88b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,30 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.23.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.22.0...v2.23.0) (2020-03-09) + + +### Bug Fixes + +* **eslint-plugin:** [prefer-readonly-parameter-types] handle recursive types ([#1672](https://github.com/typescript-eslint/typescript-eslint/issues/1672)) ([e5db36f](https://github.com/typescript-eslint/typescript-eslint/commit/e5db36f140b6463965858ad4ed77f71a9a00c5a7)), closes [#1665](https://github.com/typescript-eslint/typescript-eslint/issues/1665) +* **eslint-plugin:** [type-annotation-spacing] handle constructor types ([#1664](https://github.com/typescript-eslint/typescript-eslint/issues/1664)) ([fbf1640](https://github.com/typescript-eslint/typescript-eslint/commit/fbf1640c5ab67770a1ace5a9bad2bddfa35bd88d)), closes [#1663](https://github.com/typescript-eslint/typescript-eslint/issues/1663) +* **eslint-plugin:** fix autofixer for computed properties ([#1662](https://github.com/typescript-eslint/typescript-eslint/issues/1662)) ([ba22ea7](https://github.com/typescript-eslint/typescript-eslint/commit/ba22ea7f604b236828ce4dcff75831ec1da01ec1)) +* **eslint-plugin:** fix placeholder in `ban-ts-comment` ([#1703](https://github.com/typescript-eslint/typescript-eslint/issues/1703)) ([144345c](https://github.com/typescript-eslint/typescript-eslint/commit/144345c4774c0664752116ef2cf28f46cf52052f)) + + +### Features + +* **eslint-plugin:** [no-unsafe-call] support tagged templates ([#1680](https://github.com/typescript-eslint/typescript-eslint/issues/1680)) ([55a58ff](https://github.com/typescript-eslint/typescript-eslint/commit/55a58ff0ae0434970537657ec2cb0bc7ab64c13d)) +* **eslint-plugin:** [no-unsafe-member-access] report any typed… ([#1683](https://github.com/typescript-eslint/typescript-eslint/issues/1683)) ([1543117](https://github.com/typescript-eslint/typescript-eslint/commit/1543117874047726a6bc1b71bd2f68779f266591)) +* **eslint-plugin:** add rule no-unsafe-call ([#1647](https://github.com/typescript-eslint/typescript-eslint/issues/1647)) ([91423e4](https://github.com/typescript-eslint/typescript-eslint/commit/91423e49d19163fae7b03cbc79bb3cd3db8c2c6d)) +* **eslint-plugin:** add rule no-unsafe-member-access ([#1643](https://github.com/typescript-eslint/typescript-eslint/issues/1643)) ([608a750](https://github.com/typescript-eslint/typescript-eslint/commit/608a750d53c39e892fdb982aeea9e4f9c5e2382d)) +* **eslint-plugin:** add rule no-unsafe-return ([#1644](https://github.com/typescript-eslint/typescript-eslint/issues/1644)) ([cfc3ef1](https://github.com/typescript-eslint/typescript-eslint/commit/cfc3ef10941f46cdbc084e99e1d48d6d3a928903)) +* **typescript-estree:** support 3.8 import/export type ([#1697](https://github.com/typescript-eslint/typescript-eslint/issues/1697)) ([625d603](https://github.com/typescript-eslint/typescript-eslint/commit/625d603f94bf0521f834313bf31c734ce4948b7a)) + + + + + # [2.22.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.21.0...v2.22.0) (2020-03-02) diff --git a/lerna.json b/lerna.json index cf1d022fc59c..0c6d9da656cb 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.22.0", + "version": "2.23.0", "npmClient": "yarn", "useWorkspaces": true, "stream": true diff --git a/package.json b/package.json index 38c82e807896..db9c7201528c 100644 --- a/package.json +++ b/package.json @@ -74,9 +74,9 @@ "ts-jest": "^25.0.0", "ts-node": "^8.5.0", "tslint": "^5.20.1", - "typescript": ">=3.2.1 <3.8.0" + "typescript": ">=3.2.1 <3.9.0" }, "resolutions": { - "typescript": "^3.7.2" + "typescript": "^3.8.3" } } diff --git a/packages/eslint-plugin-internal/CHANGELOG.md b/packages/eslint-plugin-internal/CHANGELOG.md index 893f85ee9678..9160fae9e2e9 100644 --- a/packages/eslint-plugin-internal/CHANGELOG.md +++ b/packages/eslint-plugin-internal/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.23.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.22.0...v2.23.0) (2020-03-09) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal + + + + + # [2.22.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.21.0...v2.22.0) (2020-03-02) **Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal diff --git a/packages/eslint-plugin-internal/package.json b/packages/eslint-plugin-internal/package.json index 2cb24bd5db5c..38f95dadac05 100644 --- a/packages/eslint-plugin-internal/package.json +++ b/packages/eslint-plugin-internal/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin-internal", - "version": "2.22.0", + "version": "2.23.0", "private": true, "main": "dist/index.js", "scripts": { @@ -12,6 +12,6 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "2.22.0" + "@typescript-eslint/experimental-utils": "2.23.0" } } diff --git a/packages/eslint-plugin-tslint/CHANGELOG.md b/packages/eslint-plugin-tslint/CHANGELOG.md index 5aa674c15128..029236988fe5 100644 --- a/packages/eslint-plugin-tslint/CHANGELOG.md +++ b/packages/eslint-plugin-tslint/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.23.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.22.0...v2.23.0) (2020-03-09) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint + + + + + # [2.22.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.21.0...v2.22.0) (2020-03-02) **Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint diff --git a/packages/eslint-plugin-tslint/package.json b/packages/eslint-plugin-tslint/package.json index f53880af4572..225d803421d8 100644 --- a/packages/eslint-plugin-tslint/package.json +++ b/packages/eslint-plugin-tslint/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin-tslint", - "version": "2.22.0", + "version": "2.23.0", "main": "dist/index.js", "typings": "src/index.ts", "description": "TSLint wrapper plugin for ESLint", @@ -31,7 +31,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "2.22.0", + "@typescript-eslint/experimental-utils": "2.23.0", "lodash": "^4.17.15" }, "peerDependencies": { @@ -41,6 +41,6 @@ }, "devDependencies": { "@types/lodash": "^4.14.149", - "@typescript-eslint/parser": "2.22.0" + "@typescript-eslint/parser": "2.23.0" } } diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 09fdc41818dd..6e837af6b5fa 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -3,6 +3,29 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.23.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.22.0...v2.23.0) (2020-03-09) + + +### Bug Fixes + +* **eslint-plugin:** [prefer-readonly-parameter-types] handle recursive types ([#1672](https://github.com/typescript-eslint/typescript-eslint/issues/1672)) ([e5db36f](https://github.com/typescript-eslint/typescript-eslint/commit/e5db36f140b6463965858ad4ed77f71a9a00c5a7)), closes [#1665](https://github.com/typescript-eslint/typescript-eslint/issues/1665) +* **eslint-plugin:** [type-annotation-spacing] handle constructor types ([#1664](https://github.com/typescript-eslint/typescript-eslint/issues/1664)) ([fbf1640](https://github.com/typescript-eslint/typescript-eslint/commit/fbf1640c5ab67770a1ace5a9bad2bddfa35bd88d)), closes [#1663](https://github.com/typescript-eslint/typescript-eslint/issues/1663) +* **eslint-plugin:** fix autofixer for computed properties ([#1662](https://github.com/typescript-eslint/typescript-eslint/issues/1662)) ([ba22ea7](https://github.com/typescript-eslint/typescript-eslint/commit/ba22ea7f604b236828ce4dcff75831ec1da01ec1)) +* **eslint-plugin:** fix placeholder in `ban-ts-comment` ([#1703](https://github.com/typescript-eslint/typescript-eslint/issues/1703)) ([144345c](https://github.com/typescript-eslint/typescript-eslint/commit/144345c4774c0664752116ef2cf28f46cf52052f)) + + +### Features + +* **eslint-plugin:** [no-unsafe-call] support tagged templates ([#1680](https://github.com/typescript-eslint/typescript-eslint/issues/1680)) ([55a58ff](https://github.com/typescript-eslint/typescript-eslint/commit/55a58ff0ae0434970537657ec2cb0bc7ab64c13d)) +* **eslint-plugin:** [no-unsafe-member-access] report any typed… ([#1683](https://github.com/typescript-eslint/typescript-eslint/issues/1683)) ([1543117](https://github.com/typescript-eslint/typescript-eslint/commit/1543117874047726a6bc1b71bd2f68779f266591)) +* **eslint-plugin:** add rule no-unsafe-call ([#1647](https://github.com/typescript-eslint/typescript-eslint/issues/1647)) ([91423e4](https://github.com/typescript-eslint/typescript-eslint/commit/91423e49d19163fae7b03cbc79bb3cd3db8c2c6d)) +* **eslint-plugin:** add rule no-unsafe-member-access ([#1643](https://github.com/typescript-eslint/typescript-eslint/issues/1643)) ([608a750](https://github.com/typescript-eslint/typescript-eslint/commit/608a750d53c39e892fdb982aeea9e4f9c5e2382d)) +* **eslint-plugin:** add rule no-unsafe-return ([#1644](https://github.com/typescript-eslint/typescript-eslint/issues/1644)) ([cfc3ef1](https://github.com/typescript-eslint/typescript-eslint/commit/cfc3ef10941f46cdbc084e99e1d48d6d3a928903)) + + + + + # [2.22.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.21.0...v2.22.0) (2020-03-02) diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index 19ee2638a8e7..b79277579247 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -132,6 +132,9 @@ Pro Tip: For larger codebases you may want to consider splitting our linting int | [`@typescript-eslint/no-unnecessary-qualifier`](./docs/rules/no-unnecessary-qualifier.md) | Warns when a namespace qualifier is unnecessary | | :wrench: | :thought_balloon: | | [`@typescript-eslint/no-unnecessary-type-arguments`](./docs/rules/no-unnecessary-type-arguments.md) | Enforces that type arguments will not be used if not required | | :wrench: | :thought_balloon: | | [`@typescript-eslint/no-unnecessary-type-assertion`](./docs/rules/no-unnecessary-type-assertion.md) | Warns if a type assertion does not change the type of an expression | :heavy_check_mark: | :wrench: | :thought_balloon: | +| [`@typescript-eslint/no-unsafe-call`](./docs/rules/no-unsafe-call.md) | Disallows calling an any type value | | | :thought_balloon: | +| [`@typescript-eslint/no-unsafe-member-access`](./docs/rules/no-unsafe-member-access.md) | Disallows member access on any typed variables | | | :thought_balloon: | +| [`@typescript-eslint/no-unsafe-return`](./docs/rules/no-unsafe-return.md) | Disallows returning any from a function | | | :thought_balloon: | | [`@typescript-eslint/no-unused-vars-experimental`](./docs/rules/no-unused-vars-experimental.md) | Disallow unused variables and arguments | | | :thought_balloon: | | [`@typescript-eslint/no-var-requires`](./docs/rules/no-var-requires.md) | Disallows the use of require statements except in import statements | :heavy_check_mark: | | | | [`@typescript-eslint/prefer-as-const`](./docs/rules/prefer-as-const.md) | Prefer usage of `as const` over literal type | | :wrench: | | diff --git a/packages/eslint-plugin/ROADMAP.md b/packages/eslint-plugin/ROADMAP.md index 3c7b5b4edc66..32eb363609c6 100644 --- a/packages/eslint-plugin/ROADMAP.md +++ b/packages/eslint-plugin/ROADMAP.md @@ -90,7 +90,7 @@ It lists all TSLint rules along side rules from the ESLint ecosystem that are th | [`no-this-assignment`] | ✅ | [`@typescript-eslint/no-this-alias`] | | [`no-unbound-method`] | ✅ | [`@typescript-eslint/unbound-method`] | | [`no-unnecessary-class`] | ✅ | [`@typescript-eslint/no-extraneous-class`] | -| [`no-unsafe-any`] | 🛑 | N/A | +| [`no-unsafe-any`] | 🌓 | [`@typescript-eslint/no-unsafe-member-access`][2] | | [`no-unsafe-finally`] | 🌟 | [`no-unsafe-finally`][no-unsafe-finally] | | [`no-unused-expression`] | 🌟 | [`no-unused-expressions`][no-unused-expressions] | | [`no-unused-variable`] | 🌓 | [`@typescript-eslint/no-unused-vars`] | @@ -113,6 +113,7 @@ It lists all TSLint rules along side rules from the ESLint ecosystem that are th | [`use-isnan`] | 🌟 | [`use-isnan`][use-isnan] | [1] The ESLint rule also supports silencing with an extra set of parentheses (`if ((foo = bar)) {}`)
+[2] Only checks member expressions ### Maintainability @@ -136,7 +137,6 @@ It lists all TSLint rules along side rules from the ESLint ecosystem that are th | [`prefer-readonly`] | ✅ | [`@typescript-eslint/prefer-readonly`] | | [`trailing-comma`] | 🌓 | [`comma-dangle`][comma-dangle] or [Prettier] | -[1] Only warns when importing deprecated symbols
[2] Missing support for blank-line-delimited sections ### Style @@ -174,7 +174,7 @@ It lists all TSLint rules along side rules from the ESLint ecosystem that are th | [`no-reference-import`] | ✅ | [`@typescript-eslint/triple-slash-reference`] | | [`no-trailing-whitespace`] | 🌟 | [`no-trailing-spaces`][no-trailing-spaces] | | [`no-unnecessary-callback-wrapper`] | 🛑 | N/A and this might be unsafe (i.e. with `forEach`) | -| [`no-unnecessary-else`] | 🌟 | [`no-else-return`][no-else-return] [2][2] | | [`no-unnecessary-initializer`] | 🌟 | [`no-undef-init`][no-undef-init] | | [`no-unnecessary-qualifier`] | ✅ | [`@typescript-eslint/no-unnecessary-qualifier`] | | [`number-literal-format`] | 🛑 | N/A | @@ -640,6 +640,7 @@ Relevant plugins: [`chai-expect-keywords`](https://github.com/gavinaiken/eslint- [`@typescript-eslint/semi`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/semi.md [`@typescript-eslint/no-floating-promises`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-floating-promises.md [`@typescript-eslint/no-magic-numbers`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-magic-numbers.md +[`@typescript-eslint/no-unsafe-member-access`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-unsafe-member-access.md diff --git a/packages/eslint-plugin/docs/rules/no-base-to-string.md b/packages/eslint-plugin/docs/rules/no-base-to-string.md index 4050047673b7..4e73eb6339ad 100644 --- a/packages/eslint-plugin/docs/rules/no-base-to-string.md +++ b/packages/eslint-plugin/docs/rules/no-base-to-string.md @@ -7,7 +7,7 @@ The default Object `.toString()` returns `"[object Object]"`, so this rule requi Note that `Function` provides its own `.toString()` that returns the function's code. Functions are not flagged by this rule. -This rule has some overlap with with [`restrict-plus-operands`](./restrict-plus-operands.md) and [`restrict-template-expressions`](./restrict-template-expressions.md). +This rule has some overlap with [`restrict-plus-operands`](./restrict-plus-operands.md) and [`restrict-template-expressions`](./restrict-template-expressions.md). ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-namespace.md b/packages/eslint-plugin/docs/rules/no-namespace.md index 3bcb1a3868ad..d82ad724b7b3 100644 --- a/packages/eslint-plugin/docs/rules/no-namespace.md +++ b/packages/eslint-plugin/docs/rules/no-namespace.md @@ -16,7 +16,7 @@ or more of the following you may pass an object with the options set as follows: - `allowDeclarations` set to `true` will allow you to `declare` custom TypeScript modules and namespaces (Default: `false`). - `allowDefinitionFiles` set to `true` will allow you to `declare` and use custom TypeScript modules and namespaces - inside definition files (Default: `false`). + inside definition files (Default: `true`). Examples of **incorrect** code for the default `{ "allowDeclarations": false, "allowDefinitionFiles": false }` options: diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-call.md b/packages/eslint-plugin/docs/rules/no-unsafe-call.md new file mode 100644 index 000000000000..3c18b7c1ee23 --- /dev/null +++ b/packages/eslint-plugin/docs/rules/no-unsafe-call.md @@ -0,0 +1,46 @@ +# Disallows calling an any type value (`no-unsafe-call`) + +Despite your best intentions, the `any` type can sometimes leak into your codebase. +Member access on `any` typed variables is not checked at all by TypeScript, so it creates a potential safety hole, and source of bugs in your codebase. + +## Rule Details + +This rule disallows calling any variable that is typed as `any`. + +Examples of **incorrect** code for this rule: + +```ts +declare const anyVar: any; +declare const nestedAny: { prop: any }; + +anyVar(); +anyVar.a.b(); + +nestedAny.prop(); +nestedAny.prop['a'](); + +new anyVar(); +new nestedAny.prop(); + +anyVar`foo`; +nestedAny.prop`foo`; +``` + +Examples of **correct** code for this rule: + +```ts +declare const properlyTyped: { prop: { a: () => void } }; + +nestedAny.prop.a(); + +(() => {})(); + +new Map(); + +String.raw`foo`; +``` + +## Related to + +- [`no-explicit-any`](./no-explicit-any.md) +- TSLint: [`no-unsafe-any`](https://palantir.github.io/tslint/rules/no-unsafe-any/) diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-member-access.md b/packages/eslint-plugin/docs/rules/no-unsafe-member-access.md new file mode 100644 index 000000000000..29c8ea3dd97b --- /dev/null +++ b/packages/eslint-plugin/docs/rules/no-unsafe-member-access.md @@ -0,0 +1,54 @@ +# Disallows member access on any typed variables (`no-unsafe-member-access`) + +Despite your best intentions, the `any` type can sometimes leak into your codebase. +Member access on `any` typed variables is not checked at all by TypeScript, so it creates a potential safety hole, and source of bugs in your codebase. + +## Rule Details + +This rule disallows member access on any variable that is typed as `any`. + +Examples of **incorrect** code for this rule: + +```ts +declare const anyVar: any; +declare const nestedAny: { prop: any }; + +anyVar.a; +anyVar.a.b; +anyVar['a']; +anyVar['a']['b']; + +nestedAny.prop.a; +nestedAny.prop['a']; + +const key = 'a'; +nestedAny.prop[key]; + +// usng an any to access a member is unsafe +const arr = [1, 2, 3]; +arr[anyVar]; +nestedAny[anyVar]; +``` + +Examples of **correct** code for this rule: + +```ts +declare const properlyTyped: { prop: { a: string } }; + +nestedAny.prop.a; +nestedAny.prop['a']; + +const key = 'a'; +nestedAny.prop[key]; + +const arr = [1, 2, 3]; +arr[1]; +const idx = 1; +arr[idx]; +arr[idx++]; +``` + +## Related to + +- [`no-explicit-any`](./no-explicit-any.md) +- TSLint: [`no-unsafe-any`](https://palantir.github.io/tslint/rules/no-unsafe-any/) diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-return.md b/packages/eslint-plugin/docs/rules/no-unsafe-return.md new file mode 100644 index 000000000000..507abc3dfa28 --- /dev/null +++ b/packages/eslint-plugin/docs/rules/no-unsafe-return.md @@ -0,0 +1,75 @@ +# Disallows returning any from a function (`no-unsafe-return`) + +Despite your best intentions, the `any` type can sometimes leak into your codebase. +Returned `any` typed values not checked at all by TypeScript, so it creates a potential safety hole, and source of bugs in your codebase. + +## Rule Details + +This rule disallows returning `any` or `any[]` from a function. +This rule also compares the return type to the function's declared/inferred return type to ensure you don't return an unsafe `any` in a generic position to a receiver that's expecting a specific type. For example, it will error if you return `Set` from a function declared as returning `Set`. + +Examples of **incorrect** code for this rule: + +```ts +function foo1() { + return 1 as any; +} +function foo2() { + return Object.create(null); +} +const foo3 = () => { + return 1 as any; +}; +const foo4 = () => Object.create(null); + +function foo5() { + return [] as any[]; +} +function foo6() { + return [] as Array; +} +function foo7() { + return [] as readonly any[]; +} +function foo8() { + return [] as Readonly; +} +const foo9 = () => { + return [] as any[]; +}; +const foo10 = () => [] as any[]; + +const foo11 = (): string[] => [1, 2, 3] as any[]; + +// generic position examples +function assignability1(): Set { + return new Set([1]); +} +type TAssign = () => Set; +const assignability2: TAssign = () => new Set([true]); +``` + +Examples of **correct** code for this rule: + +```ts +function foo1() { + return 1; +} +function foo2() { + return Object.create(null) as Record; +} + +const foo3 = () => []; +const foo4 = () => ['a']; + +function assignability1(): Set { + return new Set(['foo']); +} +type TAssign = () => Set; +const assignability2: TAssign = () => new Set(['foo']); +``` + +## Related to + +- [`no-explicit-any`](./no-explicit-any.md) +- TSLint: [`no-unsafe-any`](https://palantir.github.io/tslint/rules/no-unsafe-any/) diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index acee148c5f99..a8dffa55c69c 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin", - "version": "2.22.0", + "version": "2.23.0", "description": "TypeScript plugin for ESLint", "keywords": [ "eslint", @@ -41,7 +41,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "2.22.0", + "@typescript-eslint/experimental-utils": "2.23.0", "eslint-utils": "^1.4.3", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.0.0", diff --git a/packages/eslint-plugin/src/configs/all.json b/packages/eslint-plugin/src/configs/all.json index 590ef81df8d5..2626767b84cc 100644 --- a/packages/eslint-plugin/src/configs/all.json +++ b/packages/eslint-plugin/src/configs/all.json @@ -61,6 +61,9 @@ "@typescript-eslint/no-unnecessary-qualifier": "error", "@typescript-eslint/no-unnecessary-type-arguments": "error", "@typescript-eslint/no-unnecessary-type-assertion": "error", + "@typescript-eslint/no-unsafe-call": "error", + "@typescript-eslint/no-unsafe-member-access": "error", + "@typescript-eslint/no-unsafe-return": "error", "no-unused-expressions": "off", "@typescript-eslint/no-unused-expressions": "error", "no-unused-vars": "off", diff --git a/packages/eslint-plugin/src/rules/ban-ts-comment.ts b/packages/eslint-plugin/src/rules/ban-ts-comment.ts index 54e2394415bb..53505cfea22d 100644 --- a/packages/eslint-plugin/src/rules/ban-ts-comment.ts +++ b/packages/eslint-plugin/src/rules/ban-ts-comment.ts @@ -28,7 +28,7 @@ export default util.createRule<[Options], MessageIds>({ }, messages: { tsDirectiveComment: - 'Do not use "// @ts-{directive}" because it alters compilation errors.', + 'Do not use "// @ts-{{directive}}" because it alters compilation errors.', }, schema: [ { diff --git a/packages/eslint-plugin/src/rules/index.ts b/packages/eslint-plugin/src/rules/index.ts index 3568057787b2..486b8a97945b 100644 --- a/packages/eslint-plugin/src/rules/index.ts +++ b/packages/eslint-plugin/src/rules/index.ts @@ -53,6 +53,9 @@ import noUnnecessaryCondition from './no-unnecessary-condition'; import noUnnecessaryQualifier from './no-unnecessary-qualifier'; import noUnnecessaryTypeArguments from './no-unnecessary-type-arguments'; import noUnnecessaryTypeAssertion from './no-unnecessary-type-assertion'; +import noUnsafeCall from './no-unsafe-call'; +import noUnsafeMemberAccess from './no-unsafe-member-access'; +import noUnsafeReturn from './no-unsafe-return'; import noUntypedPublicSignature from './no-untyped-public-signature'; import noUnusedExpressions from './no-unused-expressions'; import noUnusedVars from './no-unused-vars'; @@ -144,6 +147,9 @@ export default { 'no-unnecessary-qualifier': noUnnecessaryQualifier, 'no-unnecessary-type-arguments': noUnnecessaryTypeArguments, 'no-unnecessary-type-assertion': noUnnecessaryTypeAssertion, + 'no-unsafe-call': noUnsafeCall, + 'no-unsafe-member-access': noUnsafeMemberAccess, + 'no-unsafe-return': noUnsafeReturn, 'no-untyped-public-signature': noUntypedPublicSignature, 'no-unused-expressions': noUnusedExpressions, 'no-unused-vars-experimental': noUnusedVarsExperimental, diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts index 22a9fed5ba65..45af1e807065 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts @@ -403,7 +403,7 @@ export default createRule({ function checkOptionalMemberExpression( node: TSESTree.OptionalMemberExpression, ): void { - checkOptionalChain(node, node.object, '.'); + checkOptionalChain(node, node.object, node.computed ? '' : '.'); } function checkOptionalCallExpression( diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts index 943beb459d7e..dd4395b290b8 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts @@ -1,12 +1,7 @@ import { TSESTree } from '@typescript-eslint/experimental-utils'; import { - isCallExpression, - isJsxExpression, - isNewExpression, isObjectType, isObjectFlagSet, - isParameterDeclaration, - isPropertyDeclaration, isStrictCompilerOptionEnabled, isTypeFlagSet, isVariableDeclaration, @@ -91,48 +86,6 @@ export default util.createRule({ return true; } - /** - * Returns the contextual type of a given node. - * Contextual type is the type of the target the node is going into. - * i.e. the type of a called function's parameter, or the defined type of a variable declaration - */ - function getContextualType( - checker: ts.TypeChecker, - node: ts.Expression, - ): ts.Type | undefined { - const parent = node.parent; - if (!parent) { - return; - } - - if (isCallExpression(parent) || isNewExpression(parent)) { - if (node === parent.expression) { - // is the callee, so has no contextual type - return; - } - } else if ( - isVariableDeclaration(parent) || - isPropertyDeclaration(parent) || - isParameterDeclaration(parent) - ) { - 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, - ) - ) { - // parent is not something we know we can get the contextual type of - return; - } - // TODO - support return statement checking - - return checker.getContextualType(node); - } - /** * Returns true if there's a chance the variable has been used before a value has been assigned to it */ @@ -196,7 +149,7 @@ export default util.createRule({ // we know it's a nullable type // so figure out if the variable is used in a place that accepts nullable types - const contextualType = getContextualType(checker, originalNode); + const contextualType = util.getContextualType(checker, originalNode); if (contextualType) { // in strict mode you can't assign null to undefined, so we have to make sure that // the two types share a nullable type diff --git a/packages/eslint-plugin/src/rules/no-unsafe-call.ts b/packages/eslint-plugin/src/rules/no-unsafe-call.ts new file mode 100644 index 000000000000..42630181936a --- /dev/null +++ b/packages/eslint-plugin/src/rules/no-unsafe-call.ts @@ -0,0 +1,57 @@ +import { TSESTree } from '@typescript-eslint/experimental-utils'; +import * as util from '../util'; + +type MessageIds = 'unsafeCall' | 'unsafeNew' | 'unsafeTemplateTag'; + +export default util.createRule<[], MessageIds>({ + name: 'no-unsafe-call', + meta: { + type: 'problem', + docs: { + description: 'Disallows calling an any type value', + category: 'Possible Errors', + recommended: false, + requiresTypeChecking: true, + }, + messages: { + unsafeCall: 'Unsafe call of an any typed value', + unsafeNew: 'Unsafe construction of an any type value', + unsafeTemplateTag: 'Unsafe any typed template tag', + }, + schema: [], + }, + defaultOptions: [], + create(context) { + const { program, esTreeNodeToTSNodeMap } = util.getParserServices(context); + const checker = program.getTypeChecker(); + + function checkCall( + node: TSESTree.Node, + reportingNode: TSESTree.Node, + messageId: MessageIds, + ): void { + const tsNode = esTreeNodeToTSNodeMap.get(node); + const type = checker.getTypeAtLocation(tsNode); + if (util.isTypeAnyType(type)) { + context.report({ + node: reportingNode, + messageId: messageId, + }); + } + } + + return { + 'CallExpression, OptionalCallExpression'( + node: TSESTree.CallExpression | TSESTree.OptionalCallExpression, + ): void { + checkCall(node.callee, node.callee, 'unsafeCall'); + }, + NewExpression(node): void { + checkCall(node.callee, node, 'unsafeNew'); + }, + 'TaggedTemplateExpression > *.tag'(node: TSESTree.Node): void { + checkCall(node, node, 'unsafeTemplateTag'); + }, + }; + }, +}); diff --git a/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts b/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts new file mode 100644 index 000000000000..3d3b0c7e7231 --- /dev/null +++ b/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts @@ -0,0 +1,108 @@ +import { + TSESTree, + AST_NODE_TYPES, +} from '@typescript-eslint/experimental-utils'; +import * as util from '../util'; + +const enum State { + Unsafe = 1, + Safe = 2, +} + +export default util.createRule({ + name: 'no-unsafe-member-access', + meta: { + type: 'problem', + docs: { + description: 'Disallows member access on any typed variables', + category: 'Possible Errors', + recommended: false, + requiresTypeChecking: true, + }, + messages: { + unsafeMemberExpression: + 'Unsafe member access {{property}} on an any value', + unsafeComputedMemberAccess: + 'Computed name {{property}} resolves to an any value', + }, + schema: [], + }, + defaultOptions: [], + create(context) { + const { program, esTreeNodeToTSNodeMap } = util.getParserServices(context); + const checker = program.getTypeChecker(); + const sourceCode = context.getSourceCode(); + + const stateCache = new Map(); + + function checkMemberExpression( + node: TSESTree.MemberExpression | TSESTree.OptionalMemberExpression, + ): State { + const cachedState = stateCache.get(node); + if (cachedState) { + return cachedState; + } + + if (util.isMemberOrOptionalMemberExpression(node.object)) { + const objectState = checkMemberExpression(node.object); + if (objectState === State.Unsafe) { + // if the object is unsafe, we know this will be unsafe as well + // we don't need to report, as we have already reported on the inner member expr + stateCache.set(node, objectState); + return objectState; + } + } + + const tsNode = esTreeNodeToTSNodeMap.get(node.object); + const type = checker.getTypeAtLocation(tsNode); + const state = util.isTypeAnyType(type) ? State.Unsafe : State.Safe; + stateCache.set(node, state); + + if (state === State.Unsafe) { + const propertyName = sourceCode.getText(node.property); + context.report({ + node, + messageId: 'unsafeMemberExpression', + data: { + property: node.computed ? `[${propertyName}]` : `.${propertyName}`, + }, + }); + } + + return state; + } + + return { + 'MemberExpression, OptionalMemberExpression': checkMemberExpression, + ':matches(MemberExpression, OptionalMemberExpression)[computed = true] > *.property'( + node: TSESTree.Expression, + ): void { + if ( + // x[1] + node.type === AST_NODE_TYPES.Literal || + // x[1++] x[++x] etc + // FUN FACT - **all** update expressions return type number, regardless of the argument's type, + // because JS engines return NaN if there the argument is not a number. + node.type === AST_NODE_TYPES.UpdateExpression + ) { + // perf optimizations - literals can obviously never be `any` + return; + } + + const tsNode = esTreeNodeToTSNodeMap.get(node); + const type = checker.getTypeAtLocation(tsNode); + + if (util.isTypeAnyType(type)) { + const propertyName = sourceCode.getText(node); + context.report({ + node, + messageId: 'unsafeComputedMemberAccess', + data: { + property: `[${propertyName}]`, + }, + }); + } + }, + }; + }, +}); diff --git a/packages/eslint-plugin/src/rules/no-unsafe-return.ts b/packages/eslint-plugin/src/rules/no-unsafe-return.ts new file mode 100644 index 000000000000..fef04cd6365f --- /dev/null +++ b/packages/eslint-plugin/src/rules/no-unsafe-return.ts @@ -0,0 +1,135 @@ +import { + TSESTree, + AST_NODE_TYPES, +} from '@typescript-eslint/experimental-utils'; +import { isExpression } from 'tsutils'; +import * as util from '../util'; + +export default util.createRule({ + name: 'no-unsafe-return', + meta: { + type: 'problem', + docs: { + description: 'Disallows returning any from a function', + category: 'Possible Errors', + recommended: false, + requiresTypeChecking: true, + }, + messages: { + unsafeReturn: 'Unsafe return of an {{type}} typed value', + unsafeReturnAssignment: + 'Unsafe return of type {{sender}} from function with return type {{receiver}}', + }, + schema: [], + }, + defaultOptions: [], + create(context) { + const { program, esTreeNodeToTSNodeMap } = util.getParserServices(context); + const checker = program.getTypeChecker(); + + function getParentFunctionNode( + node: TSESTree.Node, + ): + | TSESTree.ArrowFunctionExpression + | TSESTree.FunctionDeclaration + | TSESTree.FunctionExpression + | null { + let current = node.parent; + while (current) { + if ( + current.type === AST_NODE_TYPES.ArrowFunctionExpression || + current.type === AST_NODE_TYPES.FunctionDeclaration || + current.type === AST_NODE_TYPES.FunctionExpression + ) { + return current; + } + + current = current.parent; + } + + // this shouldn't happen in correct code, but someone may attempt to parse bad code + // the parser won't error, so we shouldn't throw here + /* istanbul ignore next */ return null; + } + + function checkReturn( + returnNode: TSESTree.Node, + reportingNode: TSESTree.Node = returnNode, + ): void { + const tsNode = esTreeNodeToTSNodeMap.get(returnNode); + const anyType = util.isAnyOrAnyArrayTypeDiscriminated(tsNode, checker); + if (anyType !== util.AnyType.Safe) { + return context.report({ + node: reportingNode, + messageId: 'unsafeReturn', + data: { + type: anyType === util.AnyType.Any ? 'any' : 'any[]', + }, + }); + } + + const functionNode = getParentFunctionNode(returnNode); + /* istanbul ignore if */ if (!functionNode) { + return; + } + + // function has an explicit return type, so ensure it's a safe return + const returnNodeType = checker.getTypeAtLocation( + esTreeNodeToTSNodeMap.get(returnNode), + ); + const functionTSNode = esTreeNodeToTSNodeMap.get(functionNode); + + // function expressions will not have their return type modified based on receiver typing + // so we have to use the contextual typing in these cases, i.e. + // const foo1: () => Set = () => new Set(); + // the return type of the arrow function is Set even though the variable is typed as Set + let functionType = isExpression(functionTSNode) + ? util.getContextualType(checker, functionTSNode) + : checker.getTypeAtLocation(functionTSNode); + if (!functionType) { + functionType = checker.getTypeAtLocation(functionTSNode); + } + + for (const signature of functionType.getCallSignatures()) { + const functionReturnType = signature.getReturnType(); + if (returnNodeType === functionReturnType) { + // don't bother checking if they're the same + // either the function is explicitly declared to return the same type + // or there was no declaration, so the return type is implicit + return; + } + + const result = util.isUnsafeAssignment( + returnNodeType, + functionReturnType, + checker, + ); + if (!result) { + return; + } + + const { sender, receiver } = result; + return context.report({ + node: reportingNode, + messageId: 'unsafeReturnAssignment', + data: { + sender: checker.typeToString(sender), + receiver: checker.typeToString(receiver), + }, + }); + } + } + + return { + ReturnStatement(node): void { + const argument = node.argument; + if (!argument) { + return; + } + + checkReturn(argument, node); + }, + 'ArrowFunctionExpression > :not(BlockStatement).body': checkReturn, + }; + }, +}); diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index 5b9dbfbaa4ad..b33ec8fd7b41 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -5,6 +5,7 @@ import { isFunction, isFunctionOrFunctionType, isIdentifier, + isTSConstructorType, isTSFunctionType, isVariableDeclarator, } from '../util'; @@ -93,7 +94,7 @@ function getRules( ): WhitespaceRule { const scope = node?.parent?.parent; - if (isTSFunctionType(scope)) { + if (isTSFunctionType(scope) || isTSConstructorType(scope)) { return rules.arrow; } else if (isIdentifier(scope)) { return getIdentifierRules(rules, scope); diff --git a/packages/eslint-plugin/src/util/astUtils.ts b/packages/eslint-plugin/src/util/astUtils.ts index a92f00eaa168..03f917e4ffbd 100644 --- a/packages/eslint-plugin/src/util/astUtils.ts +++ b/packages/eslint-plugin/src/util/astUtils.ts @@ -109,6 +109,7 @@ function isFunctionType( node: TSESTree.Node | undefined, ): node is | TSESTree.TSCallSignatureDeclaration + | TSESTree.TSConstructorType | TSESTree.TSConstructSignatureDeclaration | TSESTree.TSEmptyBodyFunctionExpression | TSESTree.TSFunctionType @@ -119,6 +120,7 @@ function isFunctionType( return [ AST_NODE_TYPES.TSCallSignatureDeclaration, + AST_NODE_TYPES.TSConstructorType, AST_NODE_TYPES.TSConstructSignatureDeclaration, AST_NODE_TYPES.TSEmptyBodyFunctionExpression, AST_NODE_TYPES.TSFunctionType, @@ -133,6 +135,7 @@ function isFunctionOrFunctionType( | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.TSCallSignatureDeclaration + | TSESTree.TSConstructorType | TSESTree.TSConstructSignatureDeclaration | TSESTree.TSEmptyBodyFunctionExpression | TSESTree.TSFunctionType @@ -146,6 +149,12 @@ function isTSFunctionType( return node?.type === AST_NODE_TYPES.TSFunctionType; } +function isTSConstructorType( + node: TSESTree.Node | undefined, +): node is TSESTree.TSConstructorType { + return node?.type === AST_NODE_TYPES.TSConstructorType; +} + function isClassOrTypeElement( node: TSESTree.Node | undefined, ): node is TSESTree.ClassElement | TSESTree.TypeElement { @@ -221,6 +230,15 @@ function isAwaitKeyword( return node?.type === AST_TOKEN_TYPES.Identifier && node.value === 'await'; } +function isMemberOrOptionalMemberExpression( + node: TSESTree.Node, +): node is TSESTree.MemberExpression | TSESTree.OptionalMemberExpression { + return ( + node.type === AST_NODE_TYPES.MemberExpression || + node.type === AST_NODE_TYPES.OptionalMemberExpression + ); +} + export { isAwaitExpression, isAwaitKeyword, @@ -231,6 +249,7 @@ export { isFunctionType, isIdentifier, isLogicalOrOperator, + isMemberOrOptionalMemberExpression, isNonNullAssertionPunctuator, isNotNonNullAssertionPunctuator, isNotOptionalChainPunctuator, @@ -238,6 +257,7 @@ export { isOptionalOptionalChain, isSetter, isTokenOnSameLine, + isTSConstructorType, isTSFunctionType, isTypeAssertion, isVariableDeclarator, diff --git a/packages/eslint-plugin/src/util/isTypeReadonly.ts b/packages/eslint-plugin/src/util/isTypeReadonly.ts index 99df07b153a7..da9529e63a9d 100644 --- a/packages/eslint-plugin/src/util/isTypeReadonly.ts +++ b/packages/eslint-plugin/src/util/isTypeReadonly.ts @@ -8,30 +8,40 @@ import { import * as ts from 'typescript'; import { nullThrows, NullThrowsReasons } from '.'; -/** - * Returns: - * - null if the type is not an array or tuple, - * - true if the type is a readonly array or readonly tuple, - * - false if the type is a mutable array or mutable tuple. - */ +const enum Readonlyness { + /** the type cannot be handled by the function */ + UnknownType = 1, + /** the type is mutable */ + Mutable = 2, + /** the type is readonly */ + Readonly = 3, +} + function isTypeReadonlyArrayOrTuple( checker: ts.TypeChecker, type: ts.Type, -): boolean | null { - function checkTypeArguments(arrayType: ts.TypeReference): boolean { + seenTypes: Set, +): Readonlyness { + function checkTypeArguments(arrayType: ts.TypeReference): Readonlyness { const typeArguments = checker.getTypeArguments(arrayType); + // this shouldn't happen in reality as: + // - tuples require at least 1 type argument + // - ReadonlyArray requires at least 1 type argument /* istanbul ignore if */ if (typeArguments.length === 0) { - // this shouldn't happen in reality as: - // - tuples require at least 1 type argument - // - ReadonlyArray requires at least 1 type argument - return true; + return Readonlyness.Readonly; } // validate the element types are also readonly - if (typeArguments.some(typeArg => !isTypeReadonly(checker, typeArg))) { - return false; + if ( + typeArguments.some( + typeArg => + isTypeReadonlyRecurser(checker, typeArg, seenTypes) === + Readonlyness.Mutable, + ) + ) { + return Readonlyness.Mutable; } - return true; + return Readonlyness.Readonly; } if (checker.isArrayType(type)) { @@ -40,8 +50,8 @@ function isTypeReadonlyArrayOrTuple( NullThrowsReasons.MissingToken('symbol', 'array type'), ); const escapedName = symbol.getEscapedName(); - if (escapedName === 'Array' && escapedName !== 'ReadonlyArray') { - return false; + if (escapedName === 'Array') { + return Readonlyness.Mutable; } return checkTypeArguments(type); @@ -49,32 +59,29 @@ function isTypeReadonlyArrayOrTuple( if (checker.isTupleType(type)) { if (!type.target.readonly) { - return false; + return Readonlyness.Mutable; } return checkTypeArguments(type); } - return null; + return Readonlyness.UnknownType; } -/** - * Returns: - * - null if the type is not an object, - * - true if the type is an object with only readonly props, - * - false if the type is an object with at least one mutable prop. - */ function isTypeReadonlyObject( checker: ts.TypeChecker, type: ts.Type, -): boolean | null { - function checkIndexSignature(kind: ts.IndexKind): boolean | null { + seenTypes: Set, +): Readonlyness { + function checkIndexSignature(kind: ts.IndexKind): Readonlyness { const indexInfo = checker.getIndexInfoOfType(type, kind); if (indexInfo) { - return indexInfo.isReadonly ? true : false; + return indexInfo.isReadonly + ? Readonlyness.Readonly + : Readonlyness.Mutable; } - return null; + return Readonlyness.UnknownType; } const properties = type.getProperties(); @@ -82,7 +89,7 @@ function isTypeReadonlyObject( // ensure the properties are marked as readonly for (const property of properties) { if (!isPropertyReadonlyInType(type, property.getEscapedName(), checker)) { - return false; + return Readonlyness.Mutable; } } @@ -97,38 +104,56 @@ function isTypeReadonlyObject( checker.getTypeOfPropertyOfType(type, property.getName()), NullThrowsReasons.MissingToken(`property "${property.name}"`, 'type'), ); - if (!isTypeReadonly(checker, propertyType)) { - return false; + + // handle recursive types. + // we only need this simple check, because a mutable recursive type will break via the above prop readonly check + if (seenTypes.has(propertyType)) { + continue; + } + + if ( + isTypeReadonlyRecurser(checker, propertyType, seenTypes) === + Readonlyness.Mutable + ) { + return Readonlyness.Mutable; } } } const isStringIndexSigReadonly = checkIndexSignature(ts.IndexKind.String); - if (isStringIndexSigReadonly === false) { + if (isStringIndexSigReadonly === Readonlyness.Mutable) { return isStringIndexSigReadonly; } const isNumberIndexSigReadonly = checkIndexSignature(ts.IndexKind.Number); - if (isNumberIndexSigReadonly === false) { + if (isNumberIndexSigReadonly === Readonlyness.Mutable) { return isNumberIndexSigReadonly; } - return true; + return Readonlyness.Readonly; } -/** - * Checks if the given type is readonly - */ -function isTypeReadonly(checker: ts.TypeChecker, type: ts.Type): boolean { +// a helper function to ensure the seenTypes map is always passed down, except by the external caller +function isTypeReadonlyRecurser( + checker: ts.TypeChecker, + type: ts.Type, + seenTypes: Set, +): Readonlyness.Readonly | Readonlyness.Mutable { + seenTypes.add(type); + if (isUnionType(type)) { // all types in the union must be readonly - return unionTypeParts(type).every(t => isTypeReadonly(checker, t)); + const result = unionTypeParts(type).every(t => + isTypeReadonlyRecurser(checker, t, seenTypes), + ); + const readonlyness = result ? Readonlyness.Readonly : Readonlyness.Mutable; + return readonlyness; } // all non-object, non-intersection types are readonly. // this should only be primitive types if (!isObjectType(type) && !isUnionOrIntersectionType(type)) { - return true; + return Readonlyness.Readonly; } // pure function types are readonly @@ -136,20 +161,31 @@ function isTypeReadonly(checker: ts.TypeChecker, type: ts.Type): boolean { type.getCallSignatures().length > 0 && type.getProperties().length === 0 ) { - return true; + return Readonlyness.Readonly; } - const isReadonlyArray = isTypeReadonlyArrayOrTuple(checker, type); - if (isReadonlyArray !== null) { + const isReadonlyArray = isTypeReadonlyArrayOrTuple(checker, type, seenTypes); + if (isReadonlyArray !== Readonlyness.UnknownType) { return isReadonlyArray; } - const isReadonlyObject = isTypeReadonlyObject(checker, type); - /* istanbul ignore else */ if (isReadonlyObject !== null) { + const isReadonlyObject = isTypeReadonlyObject(checker, type, seenTypes); + /* istanbul ignore else */ if ( + isReadonlyObject !== Readonlyness.UnknownType + ) { return isReadonlyObject; } throw new Error('Unhandled type'); } +/** + * Checks if the given type is readonly + */ +function isTypeReadonly(checker: ts.TypeChecker, type: ts.Type): boolean { + return ( + isTypeReadonlyRecurser(checker, type, new Set()) === Readonlyness.Readonly + ); +} + export { isTypeReadonly }; diff --git a/packages/eslint-plugin/src/util/types.ts b/packages/eslint-plugin/src/util/types.ts index eae3519ea214..924c68e151da 100644 --- a/packages/eslint-plugin/src/util/types.ts +++ b/packages/eslint-plugin/src/util/types.ts @@ -1,6 +1,12 @@ import { + isCallExpression, + isJsxExpression, + isNewExpression, + isParameterDeclaration, + isPropertyDeclaration, isTypeReference, isUnionOrIntersectionType, + isVariableDeclaration, unionTypeParts, } from 'tsutils'; import * as ts from 'typescript'; @@ -290,3 +296,133 @@ export function getEqualsKind(operator: string): EqualsKind | undefined { return undefined; } } + +/** + * @returns true if the type is `any` + */ +export function isTypeAnyType(type: ts.Type): boolean { + return isTypeFlagSet(type, ts.TypeFlags.Any); +} + +export const enum AnyType { + Any, + AnyArray, + Safe, +} +/** + * @returns `AnyType.Any` if the type is `any`, `AnyType.AnyArray` if the type is `any[]` or `readonly any[]`, + * otherwise it returns `AnyType.Safe`. + */ +export function isAnyOrAnyArrayTypeDiscriminated( + node: ts.Node, + checker: ts.TypeChecker, +): AnyType { + const type = checker.getTypeAtLocation(node); + if (isTypeAnyType(type)) { + return AnyType.Any; + } + if ( + checker.isArrayType(type) && + isTypeAnyType(checker.getTypeArguments(type)[0]) + ) { + return AnyType.AnyArray; + } + return AnyType.Safe; +} + +/** + * Does a simple check to see if there is an any being assigned to a non-any type. + * + * This also checks generic positions to ensure there's no unsafe sub-assignments. + * Note: in the case of generic positions, it makes the assumption that the two types are the same. + * + * @example See tests for examples + * + * @returns false if it's safe, or an object with the two types if it's unsafe + */ +export function isUnsafeAssignment( + type: ts.Type, + receiver: ts.Type, + checker: ts.TypeChecker, +): false | { sender: ts.Type; receiver: ts.Type } { + if (isTypeReference(type) && isTypeReference(receiver)) { + // TODO - figure out how to handle cases like this, + // where the types are assignable, but not the same type + /* + function foo(): ReadonlySet { return new Set(); } + + // and + + type Test = { prop: T } + type Test2 = { prop: string } + declare const a: Test; + const b: Test2 = a; + */ + + if (type.target !== receiver.target) { + // if the type references are different, assume safe, as we won't know how to compare the two types + // the generic positions might not be equivalent for both types + return false; + } + + const typeArguments = type.typeArguments ?? []; + const receiverTypeArguments = receiver.typeArguments ?? []; + + for (let i = 0; i < typeArguments.length; i += 1) { + const arg = typeArguments[i]; + const receiverArg = receiverTypeArguments[i]; + + const unsafe = isUnsafeAssignment(arg, receiverArg, checker); + if (unsafe) { + return { sender: type, receiver }; + } + } + + return false; + } + + if (isTypeAnyType(type) && !isTypeAnyType(receiver)) { + return { sender: type, receiver }; + } + return false; +} + +/** + * Returns the contextual type of a given node. + * Contextual type is the type of the target the node is going into. + * i.e. the type of a called function's parameter, or the defined type of a variable declaration + */ +export function getContextualType( + checker: ts.TypeChecker, + node: ts.Expression, +): ts.Type | undefined { + const parent = node.parent; + if (!parent) { + return; + } + + if (isCallExpression(parent) || isNewExpression(parent)) { + if (node === parent.expression) { + // is the callee, so has no contextual type + return; + } + } else if ( + isVariableDeclaration(parent) || + isPropertyDeclaration(parent) || + isParameterDeclaration(parent) + ) { + 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, + ) + ) { + // parent is not something we know we can get the contextual type of + return; + } + // TODO - support return statement checking + + return checker.getContextualType(node); +} diff --git a/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts b/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts index 3a59be879f95..c2226f7041a7 100644 --- a/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts @@ -113,7 +113,7 @@ ruleTester.run('ts-nocheck', rule, { code: '// @ts-nocheck', errors: [ { - data: { directive: 'check' }, + data: { directive: 'nocheck' }, messageId: 'tsDirectiveComment', line: 1, column: 1, @@ -124,7 +124,7 @@ ruleTester.run('ts-nocheck', rule, { code: '// @ts-nocheck: Suppress next line', errors: [ { - data: { directive: 'check' }, + data: { directive: 'nocheck' }, messageId: 'tsDirectiveComment', line: 1, column: 1, @@ -135,7 +135,7 @@ ruleTester.run('ts-nocheck', rule, { code: '/////@ts-nocheck: Suppress next line', errors: [ { - data: { directive: 'check' }, + data: { directive: 'nocheck' }, messageId: 'tsDirectiveComment', line: 1, column: 1, @@ -151,7 +151,7 @@ if (false) { `, errors: [ { - data: { directive: 'check' }, + data: { directive: 'nocheck' }, messageId: 'tsDirectiveComment', line: 3, column: 3, diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts index 0728b9202b9f..5af22f00ca02 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts @@ -222,6 +222,7 @@ anyValue?.(); let unknownValue: unknown; unknownValue?.(); `, + 'const foo = [1, 2, 3][0];', ], invalid: [ // Ensure that it's checking in all the right places @@ -575,5 +576,18 @@ foo }, ], }, + { + code: 'const foo = [1, 2, 3]?.[0];', + output: 'const foo = [1, 2, 3][0];', + errors: [ + { + messageId: 'neverOptionalChain', + line: 1, + endLine: 1, + column: 22, + endColumn: 24, + }, + ], + }, ], }); diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts new file mode 100644 index 000000000000..1930db273267 --- /dev/null +++ b/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts @@ -0,0 +1,127 @@ +import rule from '../../src/rules/no-unsafe-call'; +import { + RuleTester, + batchedSingleLineTests, + getFixturesRootDir, +} from '../RuleTester'; + +const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + parserOptions: { + project: './tsconfig.json', + tsconfigRootDir: getFixturesRootDir(), + }, +}); + +ruleTester.run('no-unsafe-call', rule, { + valid: [ + 'function foo(x: () => void) { x() }', + 'function foo(x?: { a: () => void }) { x?.a() }', + 'function foo(x: { a?: () => void }) { x.a?.() }', + 'new Map()', + 'String.raw`foo`', + ], + invalid: [ + ...batchedSingleLineTests({ + code: ` +function foo(x: any) { x() } +function foo(x: any) { x?.() } +function foo(x: any) { x.a.b.c.d.e.f.g() } +function foo(x: any) { x.a.b.c.d.e.f.g?.() } + `, + errors: [ + { + messageId: 'unsafeCall', + line: 2, + column: 24, + endColumn: 25, + }, + { + messageId: 'unsafeCall', + line: 3, + column: 24, + endColumn: 25, + }, + { + messageId: 'unsafeCall', + line: 4, + column: 24, + endColumn: 39, + }, + { + messageId: 'unsafeCall', + line: 5, + column: 24, + endColumn: 39, + }, + ], + }), + ...batchedSingleLineTests({ + code: ` +function foo(x: { a: any }) { x.a() } +function foo(x: { a: any }) { x?.a() } +function foo(x: { a: any }) { x.a?.() } + `, + errors: [ + { + messageId: 'unsafeCall', + line: 2, + column: 31, + endColumn: 34, + }, + { + messageId: 'unsafeCall', + line: 3, + column: 31, + endColumn: 35, + }, + { + messageId: 'unsafeCall', + line: 4, + column: 31, + endColumn: 34, + }, + ], + }), + ...batchedSingleLineTests({ + code: ` +function foo(x: any) { new x() } +function foo(x: { a: any }) { new x.a() } + `, + errors: [ + { + messageId: 'unsafeNew', + line: 2, + column: 24, + endColumn: 31, + }, + { + messageId: 'unsafeNew', + line: 3, + column: 31, + endColumn: 40, + }, + ], + }), + ...batchedSingleLineTests({ + code: ` +function foo(x: any) { x\`foo\` } +function foo(x: { tag: any }) { x.tag\`foo\` } + `, + errors: [ + { + messageId: 'unsafeTemplateTag', + line: 2, + column: 24, + endColumn: 25, + }, + { + messageId: 'unsafeTemplateTag', + line: 3, + column: 33, + endColumn: 38, + }, + ], + }), + ], +}); diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-member-access.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-member-access.test.ts new file mode 100644 index 000000000000..484d4690c168 --- /dev/null +++ b/packages/eslint-plugin/tests/rules/no-unsafe-member-access.test.ts @@ -0,0 +1,159 @@ +import rule from '../../src/rules/no-unsafe-member-access'; +import { + RuleTester, + batchedSingleLineTests, + getFixturesRootDir, +} from '../RuleTester'; + +const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + parserOptions: { + project: './tsconfig.json', + tsconfigRootDir: getFixturesRootDir(), + }, +}); + +ruleTester.run('no-unsafe-member-access', rule, { + valid: [ + 'function foo(x: { a: number }, y: any) { x[y++] }', + 'function foo(x: { a: number }) { x.a }', + 'function foo(x?: { a: number }) { x?.a }', + 'function foo(x: { a: number }) { x["a"] }', + 'function foo(x?: { a: number }) { x?.["a"] }', + 'function foo(x: { a: number }, y: string) { x[y] }', + 'function foo(x?: { a: number }, y: string) { x?.[y] }', + 'function foo(x: string[]) { x[1] }', + 'function foo(x?: string[]) { x?.[1++] }', + 'function foo(x?: string[]) { x?.[(1 as any)++] }', + ], + invalid: [ + ...batchedSingleLineTests({ + code: ` +function foo(x: any) { x.a } +function foo(x: any) { x.a.b.c.d.e.f.g } +function foo(x: { a: any }) { x.a.b.c.d.e.f.g } + `, + errors: [ + { + messageId: 'unsafeMemberExpression', + data: { + property: '.a', + }, + line: 2, + column: 24, + endColumn: 27, + }, + { + messageId: 'unsafeMemberExpression', + data: { + property: '.a', + }, + line: 3, + column: 24, + endColumn: 27, + }, + { + messageId: 'unsafeMemberExpression', + data: { + property: '.b', + }, + line: 4, + column: 31, + endColumn: 36, + }, + ], + }), + ...batchedSingleLineTests({ + code: ` +function foo(x: any) { x['a'] } +function foo(x: any) { x['a']['b']['c'] } + `, + errors: [ + { + messageId: 'unsafeMemberExpression', + data: { + property: "['a']", + }, + line: 2, + column: 24, + endColumn: 30, + }, + { + messageId: 'unsafeMemberExpression', + data: { + property: "['a']", + }, + line: 3, + column: 24, + endColumn: 30, + }, + ], + }), + ...batchedSingleLineTests({ + code: ` +function foo(x: { a: number }, y: any) { x[y] } +function foo(x?: { a: number }, y: any) { x?.[y] } +function foo(x: { a: number }, y: any) { x[y += 1] } +function foo(x: { a: number }, y: any) { x[1 as any] } +function foo(x: { a: number }, y: any) { x[y()] } +function foo(x: string[], y: any) { x[y] } + `, + errors: [ + { + messageId: 'unsafeComputedMemberAccess', + data: { + property: '[y]', + }, + line: 2, + column: 44, + endColumn: 45, + }, + { + messageId: 'unsafeComputedMemberAccess', + data: { + property: '[y]', + }, + line: 3, + column: 47, + endColumn: 48, + }, + { + messageId: 'unsafeComputedMemberAccess', + data: { + property: '[y += 1]', + }, + line: 4, + column: 44, + endColumn: 50, + }, + { + messageId: 'unsafeComputedMemberAccess', + data: { + property: '[1 as any]', + }, + line: 5, + column: 44, + endColumn: 52, + }, + { + messageId: 'unsafeComputedMemberAccess', + data: { + property: '[y()]', + }, + line: 6, + column: 44, + endColumn: 47, + }, + { + messageId: 'unsafeComputedMemberAccess', + data: { + property: '[y]', + }, + line: 7, + column: 39, + endColumn: 40, + }, + ], + }), + ], +}); diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-return.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-return.test.ts new file mode 100644 index 000000000000..0fdcaddf36b6 --- /dev/null +++ b/packages/eslint-plugin/tests/rules/no-unsafe-return.test.ts @@ -0,0 +1,235 @@ +import rule from '../../src/rules/no-unsafe-return'; +import { + RuleTester, + batchedSingleLineTests, + getFixturesRootDir, +} from '../RuleTester'; + +const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + parserOptions: { + project: './tsconfig.json', + tsconfigRootDir: getFixturesRootDir(), + }, +}); + +ruleTester.run('no-unsafe-return', rule, { + valid: [ + 'function foo() { return; }', + 'function foo() { return 1; }', + 'function foo() { return ""; }', + 'function foo() { return true; }', + // this actually types as `never[]` + 'function foo() { return []; }', + // explicit any generic return type is allowed, if you want to be unsafe like that + 'function foo(): Set { return new Set(); }', + // TODO - this should error, but it's hard to detect, as the type references are different + 'function foo(): ReadonlySet { return new Set(); }', + 'function foo(): Set { return new Set([1]); }', + ` + type Foo = { prop: T }; + function foo(): Foo { return ({ prop: 1 } as Foo)} + `, + ` + type Foo = { prop: any }; + function foo(): Foo { return { prop: '' } as Foo; } + `, + ], + invalid: [ + ...batchedSingleLineTests({ + code: ` +function foo() { return (1 as any); } +function foo() { return Object.create(null); } +const foo = () => { return (1 as any) }; +const foo = () => Object.create(null); + `, + errors: [ + { + messageId: 'unsafeReturn', + data: { + type: 'any', + }, + line: 2, + column: 18, + }, + { + messageId: 'unsafeReturn', + data: { + type: 'any', + }, + line: 3, + column: 18, + }, + { + messageId: 'unsafeReturn', + data: { + type: 'any', + }, + line: 4, + column: 21, + }, + { + messageId: 'unsafeReturn', + data: { + type: 'any', + }, + line: 5, + column: 19, + }, + ], + }), + ...batchedSingleLineTests({ + code: ` +function foo() { return ([] as any[]); } +function foo() { return ([] as Array); } +function foo() { return ([] as readonly any[]); } +function foo() { return ([] as Readonly); } +const foo = () => { return ([] as any[]) }; +const foo = () => ([] as any[]); + `, + errors: [ + { + messageId: 'unsafeReturn', + data: { + type: 'any[]', + }, + line: 2, + column: 18, + }, + { + messageId: 'unsafeReturn', + data: { + type: 'any[]', + }, + line: 3, + column: 18, + }, + { + messageId: 'unsafeReturn', + data: { + type: 'any[]', + }, + line: 4, + column: 18, + }, + { + messageId: 'unsafeReturn', + data: { + type: 'any[]', + }, + line: 5, + column: 18, + }, + { + messageId: 'unsafeReturn', + data: { + type: 'any[]', + }, + line: 6, + column: 21, + }, + { + messageId: 'unsafeReturn', + data: { + type: 'any[]', + }, + line: 7, + column: 20, + }, + ], + }), + ...batchedSingleLineTests({ + code: ` +function foo(): Set { return new Set(); } +function foo(): Map { return new Map(); } +function foo(): Set { return new Set(); } +function foo(): Set>> { return new Set>>(); } + `, + errors: [ + { + messageId: 'unsafeReturnAssignment', + data: { + sender: 'Set', + receiver: 'Set', + }, + line: 2, + }, + { + messageId: 'unsafeReturnAssignment', + data: { + sender: 'Map', + receiver: 'Map', + }, + line: 3, + }, + { + messageId: 'unsafeReturnAssignment', + data: { + sender: 'Set', + receiver: 'Set', + }, + line: 4, + }, + { + messageId: 'unsafeReturnAssignment', + data: { + sender: 'Set>>', + receiver: 'Set>>', + }, + line: 5, + }, + ], + }), + { + code: ` + type Fn = () => Set; + const foo1: Fn = () => new Set(); + const foo2: Fn = function test() { return new Set() }; + `, + errors: [ + { + messageId: 'unsafeReturnAssignment', + line: 3, + data: { + sender: 'Set', + receiver: 'Set', + }, + }, + { + messageId: 'unsafeReturnAssignment', + line: 4, + data: { + sender: 'Set', + receiver: 'Set', + }, + }, + ], + }, + { + code: ` + type Fn = () => Set; + function receiver(arg: Fn) {} + receiver(() => new Set()); + receiver(function test() { return new Set() }); + `, + errors: [ + { + messageId: 'unsafeReturnAssignment', + line: 4, + data: { + sender: 'Set', + receiver: 'Set', + }, + }, + { + messageId: 'unsafeReturnAssignment', + line: 5, + data: { + sender: 'Set', + receiver: 'Set', + }, + }, + ], + }, + ], +}); diff --git a/packages/eslint-plugin/tests/rules/prefer-readonly-parameter-types.test.ts b/packages/eslint-plugin/tests/rules/prefer-readonly-parameter-types.test.ts index b869e0c15eda..32caf683c77b 100644 --- a/packages/eslint-plugin/tests/rules/prefer-readonly-parameter-types.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-readonly-parameter-types.test.ts @@ -199,6 +199,34 @@ ruleTester.run('prefer-readonly-parameter-types', rule, { 'function foo(arg: readonly string[]);', // TSDeclareFunction 'type Foo = (arg: readonly string[]) => void;', // TSFunctionType 'interface Foo { foo(arg: readonly string[]): void }', // TSMethodSignature + + // https://github.com/typescript-eslint/typescript-eslint/issues/1665 + // directly recursive + ` + interface Foo { + readonly prop: Foo; + } + function foo(arg: Foo) {} + `, + // indirectly recursive + ` + interface Foo { + readonly prop: Bar; + } + interface Bar { + readonly prop: Foo; + } + function foo(arg: Foo) {} + `, + ` + interface Foo { + prop: Readonly; + } + interface Bar { + prop: Readonly; + } + function foo(arg: Readonly) {} + `, ], invalid: [ // arrays @@ -503,5 +531,98 @@ ruleTester.run('prefer-readonly-parameter-types', rule, { }, ], }, + + // https://github.com/typescript-eslint/typescript-eslint/issues/1665 + // directly recursive + { + code: ` + interface Foo { + prop: Foo; + } + function foo(arg: Foo) {} + `, + errors: [ + { + messageId: 'shouldBeReadonly', + line: 5, + column: 22, + endColumn: 30, + }, + ], + }, + { + code: ` + interface Foo { + prop: Foo; + } + function foo(arg: Readonly) {} + `, + errors: [ + { + messageId: 'shouldBeReadonly', + line: 5, + column: 22, + endColumn: 40, + }, + ], + }, + // indirectly recursive + { + code: ` + interface Foo { + prop: Bar; + } + interface Bar { + readonly prop: Foo; + } + function foo(arg: Foo) {} + `, + errors: [ + { + messageId: 'shouldBeReadonly', + line: 8, + column: 22, + endColumn: 30, + }, + ], + }, + { + code: ` + interface Foo { + prop: Bar; + } + interface Bar { + readonly prop: Foo; + } + function foo(arg: Readonly) {} + `, + errors: [ + { + messageId: 'shouldBeReadonly', + line: 8, + column: 22, + endColumn: 40, + }, + ], + }, + { + code: ` + interface Foo { + prop: Readonly; + } + interface Bar { + prop: Readonly; + } + function foo(arg: Foo) {} + `, + errors: [ + { + messageId: 'shouldBeReadonly', + line: 8, + column: 22, + endColumn: 30, + }, + ], + }, ], }); diff --git a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts index e496743afc3e..6b0a3682578c 100644 --- a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts @@ -1174,6 +1174,8 @@ interface Foo { }, ], }, + // https://github.com/typescript-eslint/typescript-eslint/issues/1663 + 'type ConstructorFn = new (...args: any[]) => any;', ], invalid: [ { diff --git a/packages/eslint-plugin/tests/util/isUnsafeAssignment.test.ts b/packages/eslint-plugin/tests/util/isUnsafeAssignment.test.ts new file mode 100644 index 000000000000..bd644832b30f --- /dev/null +++ b/packages/eslint-plugin/tests/util/isUnsafeAssignment.test.ts @@ -0,0 +1,170 @@ +import * as ts from 'typescript'; +import { TSESTree } from '@typescript-eslint/experimental-utils'; +import { parseForESLint } from '@typescript-eslint/parser'; +import path from 'path'; +import { getFixturesRootDir } from '../RuleTester'; +import { isUnsafeAssignment } from '../../src/util/types'; + +describe('isUnsafeAssignment', () => { + const rootDir = getFixturesRootDir(); + + function getTypes( + code: string, + ): { sender: ts.Type; receiver: ts.Type; checker: ts.TypeChecker } { + const { ast, services } = parseForESLint(code, { + project: './tsconfig.json', + filePath: path.join(rootDir, 'file.ts'), + tsconfigRootDir: rootDir, + }); + const checker = services.program!.getTypeChecker(); + const esTreeNodeToTSNodeMap = services.esTreeNodeToTSNodeMap!; + + const declaration = ast.body[0] as TSESTree.VariableDeclaration; + const declarator = declaration.declarations[0]; + return { + receiver: checker.getTypeAtLocation( + esTreeNodeToTSNodeMap.get(declarator.id), + ), + sender: checker.getTypeAtLocation( + esTreeNodeToTSNodeMap.get(declarator.init!), + ), + checker, + }; + } + + describe('unsafe', () => { + function expectTypesAre( + result: ReturnType, + checker: ts.TypeChecker, + senderStr: string, + receiverStr: string, + ): void { + expect(result).toBeTruthy(); + const { sender, receiver } = result as Exclude; + + expect(checker.typeToString(sender)).toBe(senderStr); + expect(checker.typeToString(receiver)).toBe(receiverStr); + } + + it('any to a non-any', () => { + const { sender, receiver, checker } = getTypes( + 'const test: string = (1 as any);', + ); + + expectTypesAre( + isUnsafeAssignment(sender, receiver, checker), + checker, + 'any', + 'string', + ); + }); + + it('any in a generic position to a non-any', () => { + const { sender, receiver, checker } = getTypes( + 'const test: Set = new Set();', + ); + + expectTypesAre( + isUnsafeAssignment(sender, receiver, checker), + checker, + 'Set', + 'Set', + ); + }); + + it('any in a generic position to a non-any (multiple generics)', () => { + const { sender, receiver, checker } = getTypes( + 'const test: Map = new Map();', + ); + + expectTypesAre( + isUnsafeAssignment(sender, receiver, checker), + checker, + 'Map', + 'Map', + ); + }); + + it('any[] in a generic position to a non-any[]', () => { + const { sender, receiver, checker } = getTypes( + 'const test: Set = new Set();', + ); + + expectTypesAre( + isUnsafeAssignment(sender, receiver, checker), + checker, + 'Set', + 'Set', + ); + }); + + it('any in a generic position to a non-any (nested)', () => { + const { sender, receiver, checker } = getTypes( + 'const test: Set>> = new Set>>();', + ); + + expectTypesAre( + isUnsafeAssignment(sender, receiver, checker), + checker, + 'Set>>', + 'Set>>', + ); + }); + }); + + describe('safe', () => { + it('non-any to a non-any', () => { + const { sender, receiver, checker } = getTypes( + 'const test: string = "";', + ); + + expect(isUnsafeAssignment(sender, receiver, checker)).toBeFalsy(); + }); + + it('non-any to a any', () => { + const { sender, receiver, checker } = getTypes('const test: any = "";'); + + expect(isUnsafeAssignment(sender, receiver, checker)).toBeFalsy(); + }); + + it('non-any in a generic position to a non-any', () => { + const { sender, receiver, checker } = getTypes( + 'const test: Set = new Set();', + ); + + expect(isUnsafeAssignment(sender, receiver, checker)).toBeFalsy(); + }); + + it('non-any in a generic position to a non-any (multiple generics)', () => { + const { sender, receiver, checker } = getTypes( + 'const test: Map = new Map();', + ); + + expect(isUnsafeAssignment(sender, receiver, checker)).toBeFalsy(); + }); + + it('non-any[] in a generic position to a non-any[]', () => { + const { sender, receiver, checker } = getTypes( + 'const test: Set = new Set();', + ); + + expect(isUnsafeAssignment(sender, receiver, checker)).toBeFalsy(); + }); + + it('non-any in a generic position to a non-any (nested)', () => { + const { sender, receiver, checker } = getTypes( + 'const test: Set>> = new Set>>();', + ); + + expect(isUnsafeAssignment(sender, receiver, checker)).toBeFalsy(); + }); + + it('non-any in a generic position to a any (nested)', () => { + const { sender, receiver, checker } = getTypes( + 'const test: Set>> = new Set>>();', + ); + + expect(isUnsafeAssignment(sender, receiver, checker)).toBeFalsy(); + }); + }); +}); diff --git a/packages/experimental-utils/CHANGELOG.md b/packages/experimental-utils/CHANGELOG.md index fc8b6a8f1d67..eecd8151141b 100644 --- a/packages/experimental-utils/CHANGELOG.md +++ b/packages/experimental-utils/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.23.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.22.0...v2.23.0) (2020-03-09) + +**Note:** Version bump only for package @typescript-eslint/experimental-utils + + + + + # [2.22.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.21.0...v2.22.0) (2020-03-02) **Note:** Version bump only for package @typescript-eslint/experimental-utils diff --git a/packages/experimental-utils/package.json b/packages/experimental-utils/package.json index 72b9c0436b3c..22237081437a 100644 --- a/packages/experimental-utils/package.json +++ b/packages/experimental-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/experimental-utils", - "version": "2.22.0", + "version": "2.23.0", "description": "(Experimental) Utilities for working with TypeScript + ESLint together", "keywords": [ "eslint", @@ -37,7 +37,7 @@ }, "dependencies": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.22.0", + "@typescript-eslint/typescript-estree": "2.23.0", "eslint-scope": "^5.0.0" }, "peerDependencies": { diff --git a/packages/parser/CHANGELOG.md b/packages/parser/CHANGELOG.md index 963551cf59c0..ce0d935eabe8 100644 --- a/packages/parser/CHANGELOG.md +++ b/packages/parser/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.23.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.22.0...v2.23.0) (2020-03-09) + + +### Features + +* **typescript-estree:** support 3.8 import/export type ([#1697](https://github.com/typescript-eslint/typescript-eslint/issues/1697)) ([625d603](https://github.com/typescript-eslint/typescript-eslint/commit/625d603f94bf0521f834313bf31c734ce4948b7a)) + + + + + # [2.22.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.21.0...v2.22.0) (2020-03-02) **Note:** Version bump only for package @typescript-eslint/parser diff --git a/packages/parser/package.json b/packages/parser/package.json index 6377cef8e36c..aae36c07deda 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/parser", - "version": "2.22.0", + "version": "2.23.0", "description": "An ESLint custom parser which leverages TypeScript ESTree", "main": "dist/parser.js", "types": "dist/parser.d.ts", @@ -43,13 +43,13 @@ }, "dependencies": { "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "2.22.0", - "@typescript-eslint/typescript-estree": "2.22.0", + "@typescript-eslint/experimental-utils": "2.23.0", + "@typescript-eslint/typescript-estree": "2.23.0", "eslint-visitor-keys": "^1.1.0" }, "devDependencies": { "@types/glob": "^7.1.1", - "@typescript-eslint/shared-fixtures": "2.22.0", + "@typescript-eslint/shared-fixtures": "2.23.0", "glob": "*" }, "peerDependenciesMeta": { diff --git a/packages/parser/tests/lib/__snapshots__/jsx.ts.snap b/packages/parser/tests/lib/__snapshots__/jsx.ts.snap index 8d9c75da11d7..d45d40982a51 100644 --- a/packages/parser/tests/lib/__snapshots__/jsx.ts.snap +++ b/packages/parser/tests/lib/__snapshots__/jsx.ts.snap @@ -651,6 +651,8 @@ Object { } `; +exports[`JSX useJSXTextNode: false fixtures/member-expression-private.src 1`] = `"Identifier expected."`; + exports[`JSX useJSXTextNode: false fixtures/member-expression-this.src 1`] = ` Object { "$id": 1, diff --git a/packages/parser/tests/lib/__snapshots__/tsx.ts.snap b/packages/parser/tests/lib/__snapshots__/tsx.ts.snap index 0fb95a3acc74..f8e20c7ce802 100644 --- a/packages/parser/tests/lib/__snapshots__/tsx.ts.snap +++ b/packages/parser/tests/lib/__snapshots__/tsx.ts.snap @@ -50,6 +50,8 @@ Object { } `; +exports[`TSX fixtures/generic-jsx-member-expression-private.src 1`] = `"Identifier expected."`; + exports[`TSX fixtures/generic-jsx-opening-element.src 1`] = ` Object { "$id": 1, diff --git a/packages/parser/tests/lib/__snapshots__/typescript.ts.snap b/packages/parser/tests/lib/__snapshots__/typescript.ts.snap index e23e1fc48747..9eea694d46d2 100644 --- a/packages/parser/tests/lib/__snapshots__/typescript.ts.snap +++ b/packages/parser/tests/lib/__snapshots__/typescript.ts.snap @@ -16384,13 +16384,165 @@ Object { } `; -exports[`typescript fixtures/basics/export-type-alias-declaration.src 1`] = ` +exports[`typescript fixtures/basics/export-type.src 1`] = ` +Object { + "$id": 2, + "block": Object { + "range": Array [ + 0, + 21, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 1, + "block": Object { + "range": Array [ + 0, + 21, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [ + Object { + "$id": 0, + "from": Object { + "$ref": 1, + }, + "identifier": Object { + "name": "foo", + "range": Array [ + 14, + 17, + ], + "type": "Identifier", + }, + "kind": "r", + "resolved": null, + "writeExpr": undefined, + }, + ], + "throughReferences": Array [ + Object { + "$ref": 0, + }, + ], + "type": "module", + "upperScope": Object { + "$ref": 2, + }, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 1, + }, + "variables": Array [], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [ + Object { + "$ref": 0, + }, + ], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 2, + }, + "variables": Array [], +} +`; + +exports[`typescript fixtures/basics/export-type-as.src 1`] = ` +Object { + "$id": 2, + "block": Object { + "range": Array [ + 0, + 24, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 1, + "block": Object { + "range": Array [ + 0, + 24, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [ + Object { + "$id": 0, + "from": Object { + "$ref": 1, + }, + "identifier": Object { + "name": "A", + "range": Array [ + 14, + 15, + ], + "type": "Identifier", + }, + "kind": "r", + "resolved": null, + "writeExpr": undefined, + }, + ], + "throughReferences": Array [ + Object { + "$ref": 0, + }, + ], + "type": "module", + "upperScope": Object { + "$ref": 2, + }, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 1, + }, + "variables": Array [], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [ + Object { + "$ref": 0, + }, + ], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 2, + }, + "variables": Array [], +} +`; + +exports[`typescript fixtures/basics/export-type-from.src 1`] = ` Object { "$id": 1, "block": Object { "range": Array [ 0, - 40, + 32, ], "type": "Program", }, @@ -16400,7 +16552,7 @@ Object { "block": Object { "range": Array [ 0, - 40, + 32, ], "type": "Program", }, @@ -16434,13 +16586,13 @@ Object { } `; -exports[`typescript fixtures/basics/export-type-class-declaration.src 1`] = ` +exports[`typescript fixtures/basics/export-type-from-as.src 1`] = ` Object { "$id": 1, "block": Object { "range": Array [ 0, - 51, + 35, ], "type": "Program", }, @@ -16450,7 +16602,7 @@ Object { "block": Object { "range": Array [ 0, - 51, + 35, ], "type": "Program", }, @@ -16484,13 +16636,13 @@ Object { } `; -exports[`typescript fixtures/basics/export-type-function-declaration.src 1`] = ` +exports[`typescript fixtures/basics/export-type-star-from.src 1`] = ` Object { "$id": 1, "block": Object { "range": Array [ 0, - 47, + 26, ], "type": "Program", }, @@ -16500,7 +16652,7 @@ Object { "block": Object { "range": Array [ 0, - 47, + 26, ], "type": "Program", }, @@ -19443,23 +19595,23 @@ Object { } `; -exports[`typescript fixtures/basics/import-type.src 1`] = ` +exports[`typescript fixtures/basics/import-type-default.src 1`] = ` Object { - "$id": 1, + "$id": 2, "block": Object { "range": Array [ 0, - 56, + 28, ], "type": "Program", }, "childScopes": Array [ Object { - "$id": 0, + "$id": 1, "block": Object { "range": Array [ 0, - 56, + 28, ], "type": "Program", }, @@ -19470,13 +19622,64 @@ Object { "throughReferences": Array [], "type": "module", "upperScope": Object { - "$ref": 1, + "$ref": 2, + }, + "variableMap": Object { + "foo": Object { + "$ref": 0, + }, }, - "variableMap": Object {}, "variableScope": Object { - "$ref": 0, + "$ref": 1, }, - "variables": Array [], + "variables": Array [ + Object { + "$id": 0, + "defs": Array [ + Object { + "name": Object { + "name": "foo", + "range": Array [ + 12, + 15, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 7, + 15, + ], + "type": "ImportDefaultSpecifier", + }, + "parent": Object { + "range": Array [ + 0, + 27, + ], + "type": "ImportDeclaration", + }, + "type": "ImportBinding", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "foo", + "range": Array [ + 12, + 15, + ], + "type": "Identifier", + }, + ], + "name": "foo", + "references": Array [], + "scope": Object { + "$ref": 1, + }, + }, + ], }, ], "functionExpressionScope": false, @@ -19487,29 +19690,29 @@ Object { "upperScope": null, "variableMap": Object {}, "variableScope": Object { - "$ref": 1, + "$ref": 2, }, "variables": Array [], } `; -exports[`typescript fixtures/basics/import-type-with-type-parameters-in-type-reference.src 1`] = ` +exports[`typescript fixtures/basics/import-type-empty.src 1`] = ` Object { - "$id": 1, + "$id": 2, "block": Object { "range": Array [ - 0, - 31, + 55, + 81, ], "type": "Program", }, "childScopes": Array [ Object { - "$id": 0, + "$id": 1, "block": Object { "range": Array [ - 0, - 31, + 55, + 81, ], "type": "Program", }, @@ -19520,13 +19723,566 @@ Object { "throughReferences": Array [], "type": "module", "upperScope": Object { - "$ref": 1, + "$ref": 2, + }, + "variableMap": Object { + "type": Object { + "$ref": 0, + }, }, - "variableMap": Object {}, "variableScope": Object { - "$ref": 0, + "$ref": 1, }, - "variables": Array [], + "variables": Array [ + Object { + "$id": 0, + "defs": Array [ + Object { + "name": Object { + "name": "type", + "range": Array [ + 62, + 66, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 62, + 66, + ], + "type": "ImportDefaultSpecifier", + }, + "parent": Object { + "range": Array [ + 55, + 80, + ], + "type": "ImportDeclaration", + }, + "type": "ImportBinding", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "type", + "range": Array [ + 62, + 66, + ], + "type": "Identifier", + }, + ], + "name": "type", + "references": Array [], + "scope": Object { + "$ref": 1, + }, + }, + ], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 2, + }, + "variables": Array [], +} +`; + +exports[`typescript fixtures/basics/import-type-error.src 1`] = ` +Object { + "$id": 3, + "block": Object { + "range": Array [ + 0, + 37, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 2, + "block": Object { + "range": Array [ + 0, + 37, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "module", + "upperScope": Object { + "$ref": 3, + }, + "variableMap": Object { + "bar": Object { + "$ref": 1, + }, + "foo": Object { + "$ref": 0, + }, + }, + "variableScope": Object { + "$ref": 2, + }, + "variables": Array [ + Object { + "$id": 0, + "defs": Array [ + Object { + "name": Object { + "name": "foo", + "range": Array [ + 12, + 15, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 7, + 15, + ], + "type": "ImportDefaultSpecifier", + }, + "parent": Object { + "range": Array [ + 0, + 36, + ], + "type": "ImportDeclaration", + }, + "type": "ImportBinding", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "foo", + "range": Array [ + 12, + 15, + ], + "type": "Identifier", + }, + ], + "name": "foo", + "references": Array [], + "scope": Object { + "$ref": 2, + }, + }, + Object { + "$id": 1, + "defs": Array [ + Object { + "name": Object { + "name": "bar", + "range": Array [ + 19, + 22, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 19, + 22, + ], + "type": "ImportSpecifier", + }, + "parent": Object { + "range": Array [ + 0, + 36, + ], + "type": "ImportDeclaration", + }, + "type": "ImportBinding", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "bar", + "range": Array [ + 19, + 22, + ], + "type": "Identifier", + }, + ], + "name": "bar", + "references": Array [], + "scope": Object { + "$ref": 2, + }, + }, + ], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 3, + }, + "variables": Array [], +} +`; + +exports[`typescript fixtures/basics/import-type-named.src 1`] = ` +Object { + "$id": 3, + "block": Object { + "range": Array [ + 0, + 37, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 2, + "block": Object { + "range": Array [ + 0, + 37, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "module", + "upperScope": Object { + "$ref": 3, + }, + "variableMap": Object { + "bar": Object { + "$ref": 1, + }, + "foo": Object { + "$ref": 0, + }, + }, + "variableScope": Object { + "$ref": 2, + }, + "variables": Array [ + Object { + "$id": 0, + "defs": Array [ + Object { + "name": Object { + "name": "foo", + "range": Array [ + 14, + 17, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 14, + 17, + ], + "type": "ImportSpecifier", + }, + "parent": Object { + "range": Array [ + 0, + 36, + ], + "type": "ImportDeclaration", + }, + "type": "ImportBinding", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "foo", + "range": Array [ + 14, + 17, + ], + "type": "Identifier", + }, + ], + "name": "foo", + "references": Array [], + "scope": Object { + "$ref": 2, + }, + }, + Object { + "$id": 1, + "defs": Array [ + Object { + "name": Object { + "name": "bar", + "range": Array [ + 19, + 22, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 19, + 22, + ], + "type": "ImportSpecifier", + }, + "parent": Object { + "range": Array [ + 0, + 36, + ], + "type": "ImportDeclaration", + }, + "type": "ImportBinding", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "bar", + "range": Array [ + 19, + 22, + ], + "type": "Identifier", + }, + ], + "name": "bar", + "references": Array [], + "scope": Object { + "$ref": 2, + }, + }, + ], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 3, + }, + "variables": Array [], +} +`; + +exports[`typescript fixtures/basics/import-type-named-as.src 1`] = ` +Object { + "$id": 2, + "block": Object { + "range": Array [ + 0, + 39, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 1, + "block": Object { + "range": Array [ + 0, + 39, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "module", + "upperScope": Object { + "$ref": 2, + }, + "variableMap": Object { + "bar": Object { + "$ref": 0, + }, + }, + "variableScope": Object { + "$ref": 1, + }, + "variables": Array [ + Object { + "$id": 0, + "defs": Array [ + Object { + "name": Object { + "name": "bar", + "range": Array [ + 21, + 24, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 14, + 24, + ], + "type": "ImportSpecifier", + }, + "parent": Object { + "range": Array [ + 0, + 38, + ], + "type": "ImportDeclaration", + }, + "type": "ImportBinding", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "bar", + "range": Array [ + 21, + 24, + ], + "type": "Identifier", + }, + ], + "name": "bar", + "references": Array [], + "scope": Object { + "$ref": 1, + }, + }, + ], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 2, + }, + "variables": Array [], +} +`; + +exports[`typescript fixtures/basics/import-type-star-as-ns.src 1`] = ` +Object { + "$id": 2, + "block": Object { + "range": Array [ + 0, + 35, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 1, + "block": Object { + "range": Array [ + 0, + 35, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "module", + "upperScope": Object { + "$ref": 2, + }, + "variableMap": Object { + "foo": Object { + "$ref": 0, + }, + }, + "variableScope": Object { + "$ref": 1, + }, + "variables": Array [ + Object { + "$id": 0, + "defs": Array [ + Object { + "name": Object { + "name": "foo", + "range": Array [ + 17, + 20, + ], + "type": "Identifier", + }, + "node": Object { + "range": Array [ + 12, + 20, + ], + "type": "ImportNamespaceSpecifier", + }, + "parent": Object { + "range": Array [ + 0, + 34, + ], + "type": "ImportDeclaration", + }, + "type": "ImportBinding", + }, + ], + "eslintUsed": undefined, + "identifiers": Array [ + Object { + "name": "foo", + "range": Array [ + 17, + 20, + ], + "type": "Identifier", + }, + ], + "name": "foo", + "references": Array [], + "scope": Object { + "$ref": 1, + }, + }, + ], }, ], "functionExpressionScope": false, @@ -19537,7 +20293,7 @@ Object { "upperScope": null, "variableMap": Object {}, "variableScope": Object { - "$ref": 1, + "$ref": 2, }, "variables": Array [], } @@ -29223,6 +29979,156 @@ Object { } `; +exports[`typescript fixtures/basics/type-alias-declaration-export.src 1`] = ` +Object { + "$id": 1, + "block": Object { + "range": Array [ + 0, + 40, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 0, + "block": Object { + "range": Array [ + 0, + 40, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "module", + "upperScope": Object { + "$ref": 1, + }, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 0, + }, + "variables": Array [], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 1, + }, + "variables": Array [], +} +`; + +exports[`typescript fixtures/basics/type-alias-declaration-export-function-type.src 1`] = ` +Object { + "$id": 1, + "block": Object { + "range": Array [ + 0, + 47, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 0, + "block": Object { + "range": Array [ + 0, + 47, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "module", + "upperScope": Object { + "$ref": 1, + }, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 0, + }, + "variables": Array [], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 1, + }, + "variables": Array [], +} +`; + +exports[`typescript fixtures/basics/type-alias-declaration-export-object-type.src 1`] = ` +Object { + "$id": 1, + "block": Object { + "range": Array [ + 0, + 51, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 0, + "block": Object { + "range": Array [ + 0, + 51, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "module", + "upperScope": Object { + "$ref": 1, + }, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 0, + }, + "variables": Array [], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 1, + }, + "variables": Array [], +} +`; + exports[`typescript fixtures/basics/type-alias-declaration-with-constrained-type-parameter.src 1`] = ` Object { "$id": 1, @@ -31406,6 +32312,106 @@ Object { } `; +exports[`typescript fixtures/basics/type-import-type.src 1`] = ` +Object { + "$id": 1, + "block": Object { + "range": Array [ + 0, + 56, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 0, + "block": Object { + "range": Array [ + 0, + 56, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "module", + "upperScope": Object { + "$ref": 1, + }, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 0, + }, + "variables": Array [], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 1, + }, + "variables": Array [], +} +`; + +exports[`typescript fixtures/basics/type-import-type-with-type-parameters-in-type-reference.src 1`] = ` +Object { + "$id": 1, + "block": Object { + "range": Array [ + 0, + 31, + ], + "type": "Program", + }, + "childScopes": Array [ + Object { + "$id": 0, + "block": Object { + "range": Array [ + 0, + 31, + ], + "type": "Program", + }, + "childScopes": Array [], + "functionExpressionScope": false, + "isStrict": true, + "references": Array [], + "throughReferences": Array [], + "type": "module", + "upperScope": Object { + "$ref": 1, + }, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 0, + }, + "variables": Array [], + }, + ], + "functionExpressionScope": false, + "isStrict": false, + "references": Array [], + "throughReferences": Array [], + "type": "global", + "upperScope": null, + "variableMap": Object {}, + "variableScope": Object { + "$ref": 1, + }, + "variables": Array [], +} +`; + exports[`typescript fixtures/basics/type-parameters-comments.src 1`] = ` Object { "$id": 8, diff --git a/packages/shared-fixtures/CHANGELOG.md b/packages/shared-fixtures/CHANGELOG.md index 33f42d16e034..0d817b532b68 100644 --- a/packages/shared-fixtures/CHANGELOG.md +++ b/packages/shared-fixtures/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.23.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.22.0...v2.23.0) (2020-03-09) + + +### Features + +* **typescript-estree:** support 3.8 import/export type ([#1697](https://github.com/typescript-eslint/typescript-eslint/issues/1697)) ([625d603](https://github.com/typescript-eslint/typescript-eslint/commit/625d603f94bf0521f834313bf31c734ce4948b7a)) + + + + + # [2.22.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.21.0...v2.22.0) (2020-03-02) **Note:** Version bump only for package @typescript-eslint/shared-fixtures diff --git a/packages/shared-fixtures/fixtures/jsx/member-expression-private.src.js b/packages/shared-fixtures/fixtures/jsx/member-expression-private.src.js new file mode 100644 index 000000000000..48691af12721 --- /dev/null +++ b/packages/shared-fixtures/fixtures/jsx/member-expression-private.src.js @@ -0,0 +1 @@ +; diff --git a/packages/shared-fixtures/fixtures/tsx/generic-jsx-member-expression-private.src.tsx b/packages/shared-fixtures/fixtures/tsx/generic-jsx-member-expression-private.src.tsx new file mode 100644 index 000000000000..df915e2afc6a --- /dev/null +++ b/packages/shared-fixtures/fixtures/tsx/generic-jsx-member-expression-private.src.tsx @@ -0,0 +1 @@ +const foo = /> diff --git a/packages/shared-fixtures/fixtures/typescript/basics/export-type-as.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/export-type-as.src.ts new file mode 100644 index 000000000000..136f3867f3d3 --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/basics/export-type-as.src.ts @@ -0,0 +1 @@ +export type { A as B }; diff --git a/packages/shared-fixtures/fixtures/typescript/basics/export-type-from-as.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/export-type-from-as.src.ts new file mode 100644 index 000000000000..b7c0650b819c --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/basics/export-type-from-as.src.ts @@ -0,0 +1 @@ +export type { B as C } from './a'; diff --git a/packages/shared-fixtures/fixtures/typescript/basics/export-type-from.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/export-type-from.src.ts new file mode 100644 index 000000000000..c0316fd93e22 --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/basics/export-type-from.src.ts @@ -0,0 +1 @@ +export type { foo } from 'bar'; diff --git a/packages/shared-fixtures/fixtures/typescript/basics/export-type-star-from.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/export-type-star-from.src.ts new file mode 100644 index 000000000000..78d72bcf6b7c --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/basics/export-type-star-from.src.ts @@ -0,0 +1 @@ +export type * from 'bar'; diff --git a/packages/shared-fixtures/fixtures/typescript/basics/export-type.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/export-type.src.ts new file mode 100644 index 000000000000..e34ea63759dc --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/basics/export-type.src.ts @@ -0,0 +1 @@ +export type { foo }; diff --git a/packages/shared-fixtures/fixtures/typescript/basics/import-type-default.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/import-type-default.src.ts new file mode 100644 index 000000000000..8ac6547e2ab3 --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/basics/import-type-default.src.ts @@ -0,0 +1 @@ +import type foo from 'bar'; diff --git a/packages/shared-fixtures/fixtures/typescript/basics/import-type-empty.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/import-type-empty.src.ts new file mode 100644 index 000000000000..58067383c448 --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/basics/import-type-empty.src.ts @@ -0,0 +1,2 @@ +// this should be treated as a normal import statement +import type from './foo'; diff --git a/packages/shared-fixtures/fixtures/typescript/basics/import-type-error.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/import-type-error.src.ts new file mode 100644 index 000000000000..2a7dc99a0c8a --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/basics/import-type-error.src.ts @@ -0,0 +1 @@ +import type foo, { bar } from 'bar'; diff --git a/packages/shared-fixtures/fixtures/typescript/basics/import-type-named-as.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/import-type-named-as.src.ts new file mode 100644 index 000000000000..c7f5ad7e2aa8 --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/basics/import-type-named-as.src.ts @@ -0,0 +1 @@ +import type { foo as bar } from 'baz'; diff --git a/packages/shared-fixtures/fixtures/typescript/basics/import-type-named.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/import-type-named.src.ts new file mode 100644 index 000000000000..1b58057fb877 --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/basics/import-type-named.src.ts @@ -0,0 +1 @@ +import type { foo, bar } from 'baz'; diff --git a/packages/shared-fixtures/fixtures/typescript/basics/import-type-star-as-ns.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/import-type-star-as-ns.src.ts new file mode 100644 index 000000000000..68cd0a8a753f --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/basics/import-type-star-as-ns.src.ts @@ -0,0 +1 @@ +import type * as foo from './bar'; diff --git a/packages/shared-fixtures/fixtures/typescript/basics/export-type-function-declaration.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/type-alias-declaration-export-function-type.src.ts similarity index 100% rename from packages/shared-fixtures/fixtures/typescript/basics/export-type-function-declaration.src.ts rename to packages/shared-fixtures/fixtures/typescript/basics/type-alias-declaration-export-function-type.src.ts diff --git a/packages/shared-fixtures/fixtures/typescript/basics/export-type-class-declaration.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/type-alias-declaration-export-object-type.src.ts similarity index 100% rename from packages/shared-fixtures/fixtures/typescript/basics/export-type-class-declaration.src.ts rename to packages/shared-fixtures/fixtures/typescript/basics/type-alias-declaration-export-object-type.src.ts diff --git a/packages/shared-fixtures/fixtures/typescript/basics/export-type-alias-declaration.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/type-alias-declaration-export.src.ts similarity index 100% rename from packages/shared-fixtures/fixtures/typescript/basics/export-type-alias-declaration.src.ts rename to packages/shared-fixtures/fixtures/typescript/basics/type-alias-declaration-export.src.ts diff --git a/packages/shared-fixtures/fixtures/typescript/basics/import-type-with-type-parameters-in-type-reference.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/type-import-type-with-type-parameters-in-type-reference.src.ts similarity index 100% rename from packages/shared-fixtures/fixtures/typescript/basics/import-type-with-type-parameters-in-type-reference.src.ts rename to packages/shared-fixtures/fixtures/typescript/basics/type-import-type-with-type-parameters-in-type-reference.src.ts diff --git a/packages/shared-fixtures/fixtures/typescript/basics/import-type.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/type-import-type.src.ts similarity index 100% rename from packages/shared-fixtures/fixtures/typescript/basics/import-type.src.ts rename to packages/shared-fixtures/fixtures/typescript/basics/type-import-type.src.ts diff --git a/packages/shared-fixtures/package.json b/packages/shared-fixtures/package.json index 69a34e083b3e..abe5c65bb613 100644 --- a/packages/shared-fixtures/package.json +++ b/packages/shared-fixtures/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/shared-fixtures", - "version": "2.22.0", + "version": "2.23.0", "private": true, "scripts": { "build": "tsc -b tsconfig.build.json", diff --git a/packages/typescript-estree/CHANGELOG.md b/packages/typescript-estree/CHANGELOG.md index ffd7ae3936bb..a163e32428e5 100644 --- a/packages/typescript-estree/CHANGELOG.md +++ b/packages/typescript-estree/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.23.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.22.0...v2.23.0) (2020-03-09) + + +### Features + +* **typescript-estree:** support 3.8 import/export type ([#1697](https://github.com/typescript-eslint/typescript-eslint/issues/1697)) ([625d603](https://github.com/typescript-eslint/typescript-eslint/commit/625d603f94bf0521f834313bf31c734ce4948b7a)) + + + + + # [2.22.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.21.0...v2.22.0) (2020-03-02) **Note:** Version bump only for package @typescript-eslint/typescript-estree diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index e58be5a1d73c..921adecc2512 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/typescript-estree", - "version": "2.22.0", + "version": "2.23.0", "description": "A parser that converts TypeScript source code into an ESTree compatible form", "main": "dist/parser.js", "types": "dist/parser.d.ts", @@ -58,7 +58,7 @@ "@types/lodash": "^4.14.149", "@types/semver": "^6.2.0", "@types/tmp": "^0.1.0", - "@typescript-eslint/shared-fixtures": "2.22.0", + "@typescript-eslint/shared-fixtures": "2.23.0", "tmp": "^0.1.0", "typescript": "*" }, diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index cc38171caf13..97dc43a5ee27 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -172,11 +172,15 @@ export class Converter { range: [exportKeyword.getStart(this.ast), result.range[1]], }); } else { + const isType = + result.type === AST_NODE_TYPES.TSInterfaceDeclaration || + result.type === AST_NODE_TYPES.TSTypeAliasDeclaration; return this.createNode(node, { type: AST_NODE_TYPES.ExportNamedDeclaration, declaration: result, specifiers: [], source: null, + exportKind: isType ? 'type' : 'value', range: [exportKeyword.getStart(this.ast), result.range[1]], }); } @@ -458,6 +462,12 @@ export class Converter { let result: TSESTree.JSXMemberExpression | TSESTree.JSXIdentifier; switch (node.kind) { case SyntaxKind.PropertyAccessExpression: + if (node.name.kind === SyntaxKind.PrivateIdentifier) { + // This is one of the few times where TS explicitly errors, and doesn't even gracefully handle the syntax. + // So we shouldn't ever get into this state to begin with. + throw new Error('Non-private identifier expected.'); + } + result = this.createNode(node, { type: AST_NODE_TYPES.JSXMemberExpression, object: this.convertJSXTagName(node.expression, parent), @@ -467,12 +477,14 @@ export class Converter { ) as TSESTree.JSXIdentifier, }); break; + case SyntaxKind.ThisKeyword: result = this.createNode(node, { type: AST_NODE_TYPES.JSXIdentifier, name: 'this', }); break; + case SyntaxKind.Identifier: default: result = this.createNode(node, { @@ -1521,9 +1533,14 @@ export class Converter { type: AST_NODE_TYPES.ImportDeclaration, source: this.convertChild(node.moduleSpecifier), specifiers: [], + importKind: 'value', }); if (node.importClause) { + if (node.importClause.isTypeOnly) { + result.importKind = 'type'; + } + if (node.importClause.name) { result.specifiers.push(this.convertChild(node.importClause)); } @@ -1570,18 +1587,23 @@ export class Converter { case SyntaxKind.ExportDeclaration: if (node.exportClause) { + if (node.exportClause.kind !== SyntaxKind.NamedExports) { + throw new Error('`export * as ns` is not yet supported.'); + } return this.createNode(node, { type: AST_NODE_TYPES.ExportNamedDeclaration, source: this.convertChild(node.moduleSpecifier), specifiers: node.exportClause.elements.map(el => this.convertChild(el), ), + exportKind: node.isTypeOnly ? 'type' : 'value', declaration: null, }); } else { return this.createNode(node, { type: AST_NODE_TYPES.ExportAllDeclaration, source: this.convertChild(node.moduleSpecifier), + exportKind: node.isTypeOnly ? 'type' : 'value', }); } diff --git a/packages/typescript-estree/src/ts-estree/ts-estree.ts b/packages/typescript-estree/src/ts-estree/ts-estree.ts index 94d4b7c24408..10685a507b94 100644 --- a/packages/typescript-estree/src/ts-estree/ts-estree.ts +++ b/packages/typescript-estree/src/ts-estree/ts-estree.ts @@ -868,6 +868,7 @@ export interface EmptyStatement extends BaseNode { export interface ExportAllDeclaration extends BaseNode { type: AST_NODE_TYPES.ExportAllDeclaration; source: Expression | null; + exportKind: 'type' | 'value'; } export interface ExportDefaultDeclaration extends BaseNode { @@ -880,6 +881,7 @@ export interface ExportNamedDeclaration extends BaseNode { declaration: ExportDeclaration | null; specifiers: ExportSpecifier[]; source: Expression | null; + exportKind: 'type' | 'value'; } export interface ExportSpecifier extends BaseNode { @@ -949,6 +951,7 @@ export interface ImportDeclaration extends BaseNode { type: AST_NODE_TYPES.ImportDeclaration; source: Literal; specifiers: ImportClause[]; + importKind: 'type' | 'value'; } export interface ImportDefaultSpecifier extends BaseNode { diff --git a/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts b/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts index ab677004678a..b970aa38f41c 100644 --- a/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts +++ b/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts @@ -379,8 +379,8 @@ tester.addFixturePatternConfig('typescript/basics', { * But not fixed in Babel 7.3 * TODO: Investigate differences */ - 'import-type', - 'import-type-with-type-parameters-in-type-reference', + 'type-import-type', + 'type-import-type-with-type-parameters-in-type-reference', /** * Not yet supported in Babel https://github.com/babel/babel/issues/9228 * Directive field is not added to module and namespace @@ -422,6 +422,20 @@ tester.addFixturePatternConfig('typescript/basics', { */ 'abstract-class-with-declare-properties', 'class-with-declare-properties', + /** + * TS 3.8 import/export type + * babel coming soon https://github.com/babel/babel/pull/11171 + */ + 'export-type-as', + 'export-type-from-as', + 'export-type-from', + 'export-type-star-from', + 'export-type', + 'import-type-default', + 'import-type-error', + 'import-type-named-as', + 'import-type-named', + 'import-type-star-as-ns', ], ignoreSourceType: [ /** diff --git a/packages/typescript-estree/tests/ast-alignment/utils.ts b/packages/typescript-estree/tests/ast-alignment/utils.ts index 002a4c66dcbd..6a2426b147f8 100644 --- a/packages/typescript-estree/tests/ast-alignment/utils.ts +++ b/packages/typescript-estree/tests/ast-alignment/utils.ts @@ -248,6 +248,48 @@ export function preprocessBabylonAST(ast: BabelTypes.File): any { node.asserts = false; } }, + /** + * TS 3.8 import/export type + * babel coming soon https://github.com/babel/babel/pull/11171 + */ + ExportNamedDeclaration(node: any) { + /** + * TS 3.8: export type + */ + if (!node.exportKind) { + if ( + node.declaration?.type === AST_NODE_TYPES.TSTypeAliasDeclaration || + node.declaration?.type === AST_NODE_TYPES.TSInterfaceDeclaration + ) { + node.exportKind = 'type'; + } else { + node.exportKind = 'value'; + } + } + }, + ExportAllDeclaration(node: any) { + /** + * TS 3.8: export type + */ + if (!node.exportKind) { + if ( + node.declaration?.type === AST_NODE_TYPES.TSTypeAliasDeclaration || + node.declaration?.type === AST_NODE_TYPES.TSInterfaceDeclaration + ) { + node.exportKind = 'type'; + } else { + node.exportKind = 'value'; + } + } + }, + ImportDeclaration(node) { + /** + * TS 3.8: export type + */ + if (!node.importKind) { + node.importKind = 'value'; + } + }, }, ); } diff --git a/packages/typescript-estree/tests/lib/__snapshots__/javascript.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/javascript.ts.snap index 0f9639a3bcb5..ef4ac4c58c16 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/javascript.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/javascript.ts.snap @@ -108235,6 +108235,7 @@ exports[`javascript fixtures/modules/error-delete.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 18, @@ -108829,6 +108830,7 @@ exports[`javascript fixtures/modules/error-strict.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 26, @@ -109472,6 +109474,7 @@ Object { ], "type": "FunctionDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 30, @@ -109734,6 +109737,7 @@ Object { ], "type": "VariableDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 21, @@ -111891,6 +111895,7 @@ exports[`javascript fixtures/modules/export-from-batch.src 1`] = ` Object { "body": Array [ Object { + "exportKind": "value", "loc": Object { "end": Object { "column": 20, @@ -112043,6 +112048,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 28, @@ -112286,6 +112292,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 35, @@ -112565,6 +112572,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 31, @@ -112844,6 +112852,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 40, @@ -113212,6 +113221,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 24, @@ -113455,6 +113465,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 29, @@ -113843,6 +113854,7 @@ Object { ], "type": "FunctionDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 25, @@ -114087,6 +114099,7 @@ Object { ], "type": "VariableDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 19, @@ -114240,6 +114253,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 24, @@ -114465,6 +114479,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 20, @@ -114690,6 +114705,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 29, @@ -115057,6 +115073,7 @@ Object { "superClass": null, "type": "ClassDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 1, @@ -115192,6 +115209,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 10, @@ -115309,6 +115327,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 13, @@ -115498,6 +115517,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 18, @@ -115776,6 +115796,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 19, @@ -116127,6 +116148,7 @@ Object { ], "type": "VariableDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 15, @@ -116338,6 +116360,7 @@ Object { ], "type": "VariableDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 32, @@ -116636,6 +116659,7 @@ Object { ], "type": "VariableDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 19, @@ -116788,6 +116812,7 @@ exports[`javascript fixtures/modules/import-default.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 22, @@ -116976,6 +117001,7 @@ exports[`javascript fixtures/modules/import-default-and-named-specifiers.src 1`] Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 29, @@ -117289,6 +117315,7 @@ exports[`javascript fixtures/modules/import-default-and-namespace-specifiers.src Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 32, @@ -117584,6 +117611,7 @@ exports[`javascript fixtures/modules/import-default-as.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 35, @@ -117862,6 +117890,7 @@ exports[`javascript fixtures/modules/import-jquery.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 22, @@ -118032,6 +118061,7 @@ exports[`javascript fixtures/modules/import-module.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 13, @@ -118148,6 +118178,7 @@ exports[`javascript fixtures/modules/import-named-as-specifier.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 31, @@ -118426,6 +118457,7 @@ exports[`javascript fixtures/modules/import-named-as-specifiers.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 36, @@ -118793,6 +118825,7 @@ exports[`javascript fixtures/modules/import-named-empty.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 21, @@ -118963,6 +118996,7 @@ exports[`javascript fixtures/modules/import-named-specifier.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 24, @@ -119205,6 +119239,7 @@ exports[`javascript fixtures/modules/import-named-specifiers.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 29, @@ -119536,6 +119571,7 @@ exports[`javascript fixtures/modules/import-named-specifiers-comma.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 30, @@ -119885,6 +119921,7 @@ exports[`javascript fixtures/modules/import-namespace-specifier.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 27, @@ -120109,6 +120146,7 @@ exports[`javascript fixtures/modules/import-null-as-nil.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 33, @@ -120425,6 +120463,7 @@ Object { ], "type": "VariableDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 17, @@ -120721,6 +120760,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 16, @@ -120903,6 +120943,7 @@ exports[`javascript fixtures/modules/invalid-import-default-module-specifier.src Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 20, @@ -121093,6 +121134,7 @@ Object { "body": Array [ Object { "declaration": null, + "exportKind": "value", "loc": Object { "end": Object { "column": 21, diff --git a/packages/typescript-estree/tests/lib/__snapshots__/jsx.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/jsx.ts.snap index 037f88206448..4dd9a5c93dd2 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/jsx.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/jsx.ts.snap @@ -5289,6 +5289,8 @@ Object { } `; +exports[`JSX useJSXTextNode: false fixtures/member-expression-private.src 1`] = `"Identifier expected."`; + exports[`JSX useJSXTextNode: false fixtures/member-expression-this.src 1`] = ` Object { "body": Array [ diff --git a/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap index 1b81d29c0842..f3189765268e 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap @@ -1555,6 +1555,15 @@ exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" e exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/jsx/member-expression.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/jsx/member-expression-private.src 1`] = ` +Object { + "column": 10, + "index": 10, + "lineNumber": 1, + "message": "Identifier expected.", +} +`; + exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/jsx/member-expression-this.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/jsx/multiple-blank-spaces.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; @@ -1627,6 +1636,15 @@ exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" e exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/tsx/generic-jsx-element.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/tsx/generic-jsx-member-expression-private.src 1`] = ` +Object { + "column": 22, + "index": 22, + "lineNumber": 1, + "message": "Identifier expected.", +} +`; + exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/tsx/generic-jsx-opening-element.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/tsx/react-typed-props.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; @@ -1689,7 +1707,7 @@ Object { "column": 14, "index": 31, "lineNumber": 2, - "message": "'await' expression is only allowed within an async function.", + "message": "'await' expressions are only allowed within async functions and at the top levels of modules.", } `; @@ -1860,11 +1878,15 @@ Object { } `; -exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/export-type-alias-declaration.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/export-type.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/export-type-as.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/export-type-from.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; -exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/export-type-class-declaration.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/export-type-from-as.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; -exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/export-type-function-declaration.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/export-type-star-from.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/function-anonymus-with-type-parameters.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; @@ -1894,9 +1916,17 @@ exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" e exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/import-export-equal-declaration.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; -exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/import-type.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/import-type-default.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/import-type-empty.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/import-type-error.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/import-type-named.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; -exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/import-type-with-type-parameters-in-type-reference.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/import-type-named-as.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/import-type-star-as-ns.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/interface-extends.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; @@ -1978,6 +2008,12 @@ exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" e exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/type-alias-declaration.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/type-alias-declaration-export.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/type-alias-declaration-export-function-type.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/type-alias-declaration-export-object-type.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/type-alias-declaration-with-constrained-type-parameter.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/type-alias-object-without-annotation.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; @@ -2006,6 +2042,10 @@ exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" e exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/type-guard-in-method.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/type-import-type.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/type-import-type-with-type-parameters-in-type-reference.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/type-parameters-comments.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/type-parameters-comments-heritage.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; diff --git a/packages/typescript-estree/tests/lib/__snapshots__/semanticInfo.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/semanticInfo.ts.snap index f6b67ce5556a..feb0d60b462b 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/semanticInfo.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/semanticInfo.ts.snap @@ -303,6 +303,7 @@ exports[`semanticInfo fixtures/import-file.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 36, diff --git a/packages/typescript-estree/tests/lib/__snapshots__/tsx.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/tsx.ts.snap index c0240d2580e9..1cda86868dc2 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/tsx.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/tsx.ts.snap @@ -422,6 +422,8 @@ Object { } `; +exports[`TSX fixtures/generic-jsx-member-expression-private.src 1`] = `"Identifier expected."`; + exports[`TSX fixtures/generic-jsx-opening-element.src 1`] = ` Object { "body": Array [ @@ -936,6 +938,7 @@ exports[`TSX fixtures/react-typed-props.src 1`] = ` Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 30, diff --git a/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap index cbd1e12b3783..dc2275c4cd30 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap @@ -823,6 +823,7 @@ Object { "superClass": null, "type": "ClassDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 1, @@ -1270,6 +1271,7 @@ Object { "superClass": null, "type": "ClassDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 1, @@ -2486,6 +2488,7 @@ Object { "superClass": null, "type": "ClassDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 1, @@ -4086,6 +4089,7 @@ Object { "superClass": null, "type": "ClassDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 1, @@ -4472,6 +4476,7 @@ Object { ], "type": "TSInterfaceDeclaration", }, + "exportKind": "type", "loc": Object { "end": Object { "column": 1, @@ -43714,6 +43719,7 @@ Object { ], "type": "TSEnumDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 1, @@ -44101,6 +44107,7 @@ Object { ], "type": "TSEnumDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 1, @@ -45076,6 +45083,7 @@ Object { "type": "TSTypeParameterDeclaration", }, }, + "exportKind": "value", "loc": Object { "end": Object { "column": 1, @@ -45407,6 +45415,7 @@ Object { "type": "TSTypeParameterDeclaration", }, }, + "exportKind": "value", "loc": Object { "end": Object { "column": 1, @@ -45757,6 +45766,7 @@ Object { ], "type": "TSEnumDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 1, @@ -46055,6 +46065,7 @@ Object { ], "type": "TSEnumDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 1, @@ -46335,6 +46346,7 @@ Object { ], "type": "TSEnumDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 1, @@ -46614,6 +46626,7 @@ Object { ], "type": "TSEnumDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 1, @@ -46816,101 +46829,223 @@ Object { } `; -exports[`typescript fixtures/basics/export-type-alias-declaration.src 1`] = ` +exports[`typescript fixtures/basics/export-type.src 1`] = ` Object { "body": Array [ Object { - "declaration": Object { - "id": Object { - "loc": Object { - "end": Object { - "column": 21, - "line": 1, - }, - "start": Object { - "column": 12, - "line": 1, - }, - }, - "name": "TestAlias", - "range": Array [ - 12, - 21, - ], - "type": "Identifier", + "declaration": null, + "exportKind": "type", + "loc": Object { + "end": Object { + "column": 20, + "line": 1, }, - "loc": Object { - "end": Object { - "column": 40, - "line": 1, - }, - "start": Object { - "column": 7, - "line": 1, - }, + "start": Object { + "column": 0, + "line": 1, }, - "range": Array [ - 7, - 40, - ], - "type": "TSTypeAliasDeclaration", - "typeAnnotation": Object { + }, + "range": Array [ + 0, + 20, + ], + "source": null, + "specifiers": Array [ + Object { + "exported": Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "name": "foo", + "range": Array [ + 14, + 17, + ], + "type": "Identifier", + }, "loc": Object { "end": Object { - "column": 39, + "column": 17, "line": 1, }, "start": Object { - "column": 24, + "column": 14, "line": 1, }, }, - "range": Array [ - 24, - 39, - ], - "type": "TSUnionType", - "types": Array [ - Object { - "loc": Object { - "end": Object { - "column": 30, - "line": 1, - }, - "start": Object { - "column": 24, - "line": 1, - }, + "local": Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, }, - "range": Array [ - 24, - 30, - ], - "type": "TSStringKeyword", - }, - Object { - "loc": Object { - "end": Object { - "column": 39, - "line": 1, - }, - "start": Object { - "column": 33, - "line": 1, - }, + "start": Object { + "column": 14, + "line": 1, }, - "range": Array [ - 33, - 39, - ], - "type": "TSNumberKeyword", }, + "name": "foo", + "range": Array [ + 14, + 17, + ], + "type": "Identifier", + }, + "range": Array [ + 14, + 17, ], + "type": "ExportSpecifier", + }, + ], + "type": "ExportNamedDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 21, + ], + "sourceType": "module", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 6, + ], + "type": "Keyword", + "value": "export", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, }, }, + "range": Array [ + 7, + 11, + ], + "type": "Identifier", + "value": "type", + }, + Object { "loc": Object { "end": Object { - "column": 40, + "column": 13, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "range": Array [ + 12, + 13, + ], + "type": "Punctuator", + "value": "{", + }, + Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "range": Array [ + 14, + 17, + ], + "type": "Identifier", + "value": "foo", + }, + Object { + "loc": Object { + "end": Object { + "column": 19, + "line": 1, + }, + "start": Object { + "column": 18, + "line": 1, + }, + }, + "range": Array [ + 18, + 19, + ], + "type": "Punctuator", + "value": "}", + }, + Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "range": Array [ + 19, + 20, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; + +exports[`typescript fixtures/basics/export-type-as.src 1`] = ` +Object { + "body": Array [ + Object { + "declaration": null, + "exportKind": "type", + "loc": Object { + "end": Object { + "column": 23, "line": 1, }, "start": Object { @@ -46920,17 +47055,71 @@ Object { }, "range": Array [ 0, - 40, + 23, ], "source": null, - "specifiers": Array [], + "specifiers": Array [ + Object { + "exported": Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "name": "B", + "range": Array [ + 19, + 20, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "local": Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "name": "A", + "range": Array [ + 14, + 15, + ], + "type": "Identifier", + }, + "range": Array [ + 14, + 20, + ], + "type": "ExportSpecifier", + }, + ], "type": "ExportNamedDeclaration", }, ], "loc": Object { "end": Object { - "column": 40, - "line": 1, + "column": 0, + "line": 2, }, "start": Object { "column": 0, @@ -46939,7 +47128,7 @@ Object { }, "range": Array [ 0, - 40, + 24, ], "sourceType": "module", "tokens": Array [ @@ -46982,7 +47171,7 @@ Object { Object { "loc": Object { "end": Object { - "column": 21, + "column": 13, "line": 1, }, "start": Object { @@ -46992,97 +47181,97 @@ Object { }, "range": Array [ 12, - 21, + 13, ], - "type": "Identifier", - "value": "TestAlias", + "type": "Punctuator", + "value": "{", }, Object { "loc": Object { "end": Object { - "column": 23, + "column": 15, "line": 1, }, "start": Object { - "column": 22, + "column": 14, "line": 1, }, }, "range": Array [ - 22, - 23, + 14, + 15, ], - "type": "Punctuator", - "value": "=", + "type": "Identifier", + "value": "A", }, Object { "loc": Object { "end": Object { - "column": 30, + "column": 18, "line": 1, }, "start": Object { - "column": 24, + "column": 16, "line": 1, }, }, "range": Array [ - 24, - 30, + 16, + 18, ], "type": "Identifier", - "value": "string", + "value": "as", }, Object { "loc": Object { "end": Object { - "column": 32, + "column": 20, "line": 1, }, "start": Object { - "column": 31, + "column": 19, "line": 1, }, }, "range": Array [ - 31, - 32, + 19, + 20, ], - "type": "Punctuator", - "value": "|", + "type": "Identifier", + "value": "B", }, Object { "loc": Object { "end": Object { - "column": 39, + "column": 22, "line": 1, }, "start": Object { - "column": 33, + "column": 21, "line": 1, }, }, "range": Array [ - 33, - 39, + 21, + 22, ], - "type": "Identifier", - "value": "number", + "type": "Punctuator", + "value": "}", }, Object { "loc": Object { "end": Object { - "column": 40, + "column": 23, "line": 1, }, "start": Object { - "column": 39, + "column": 22, "line": 1, }, }, "range": Array [ - 39, - 40, + 22, + 23, ], "type": "Punctuator", "value": ";", @@ -47092,157 +47281,107 @@ Object { } `; -exports[`typescript fixtures/basics/export-type-class-declaration.src 1`] = ` +exports[`typescript fixtures/basics/export-type-from.src 1`] = ` Object { "body": Array [ Object { - "declaration": Object { - "id": Object { - "loc": Object { - "end": Object { - "column": 26, - "line": 1, - }, - "start": Object { - "column": 12, - "line": 1, - }, - }, - "name": "TestClassProps", - "range": Array [ - 12, - 26, - ], - "type": "Identifier", + "declaration": null, + "exportKind": "type", + "loc": Object { + "end": Object { + "column": 31, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, }, + }, + "range": Array [ + 0, + 31, + ], + "source": Object { "loc": Object { "end": Object { - "column": 2, - "line": 3, + "column": 30, + "line": 1, }, "start": Object { - "column": 7, + "column": 25, "line": 1, }, }, "range": Array [ - 7, - 51, + 25, + 30, ], - "type": "TSTypeAliasDeclaration", - "typeAnnotation": Object { + "raw": "'bar'", + "type": "Literal", + "value": "bar", + }, + "specifiers": Array [ + Object { + "exported": Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "name": "foo", + "range": Array [ + 14, + 17, + ], + "type": "Identifier", + }, "loc": Object { "end": Object { - "column": 1, - "line": 3, + "column": 17, + "line": 1, }, "start": Object { - "column": 29, + "column": 14, "line": 1, }, }, - "members": Array [ - Object { - "computed": false, - "key": Object { - "loc": Object { - "end": Object { - "column": 9, - "line": 2, - }, - "start": Object { - "column": 4, - "line": 2, - }, - }, - "name": "count", - "range": Array [ - 35, - 40, - ], - "type": "Identifier", - }, - "loc": Object { - "end": Object { - "column": 17, - "line": 2, - }, - "start": Object { - "column": 4, - "line": 2, - }, + "local": Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, }, - "range": Array [ - 35, - 48, - ], - "type": "TSPropertySignature", - "typeAnnotation": Object { - "loc": Object { - "end": Object { - "column": 17, - "line": 2, - }, - "start": Object { - "column": 9, - "line": 2, - }, - }, - "range": Array [ - 40, - 48, - ], - "type": "TSTypeAnnotation", - "typeAnnotation": Object { - "loc": Object { - "end": Object { - "column": 17, - "line": 2, - }, - "start": Object { - "column": 11, - "line": 2, - }, - }, - "range": Array [ - 42, - 48, - ], - "type": "TSNumberKeyword", - }, + "start": Object { + "column": 14, + "line": 1, }, }, - ], + "name": "foo", + "range": Array [ + 14, + 17, + ], + "type": "Identifier", + }, "range": Array [ - 29, - 50, + 14, + 17, ], - "type": "TSTypeLiteral", - }, - }, - "loc": Object { - "end": Object { - "column": 2, - "line": 3, - }, - "start": Object { - "column": 0, - "line": 1, + "type": "ExportSpecifier", }, - }, - "range": Array [ - 0, - 51, ], - "source": null, - "specifiers": Array [], "type": "ExportNamedDeclaration", }, ], "loc": Object { "end": Object { - "column": 2, - "line": 3, + "column": 0, + "line": 2, }, "start": Object { "column": 0, @@ -47251,7 +47390,7 @@ Object { }, "range": Array [ 0, - 51, + 32, ], "sourceType": "module", "tokens": Array [ @@ -47294,7 +47433,7 @@ Object { Object { "loc": Object { "end": Object { - "column": 26, + "column": 13, "line": 1, }, "start": Object { @@ -47304,133 +47443,97 @@ Object { }, "range": Array [ 12, - 26, - ], - "type": "Identifier", - "value": "TestClassProps", - }, - Object { - "loc": Object { - "end": Object { - "column": 28, - "line": 1, - }, - "start": Object { - "column": 27, - "line": 1, - }, - }, - "range": Array [ - 27, - 28, + 13, ], "type": "Punctuator", - "value": "=", + "value": "{", }, Object { "loc": Object { "end": Object { - "column": 30, + "column": 17, "line": 1, }, "start": Object { - "column": 29, + "column": 14, "line": 1, }, }, "range": Array [ - 29, - 30, - ], - "type": "Punctuator", - "value": "{", - }, - Object { - "loc": Object { - "end": Object { - "column": 9, - "line": 2, - }, - "start": Object { - "column": 4, - "line": 2, - }, - }, - "range": Array [ - 35, - 40, + 14, + 17, ], "type": "Identifier", - "value": "count", + "value": "foo", }, Object { "loc": Object { "end": Object { - "column": 10, - "line": 2, + "column": 19, + "line": 1, }, "start": Object { - "column": 9, - "line": 2, + "column": 18, + "line": 1, }, }, "range": Array [ - 40, - 41, + 18, + 19, ], "type": "Punctuator", - "value": ":", + "value": "}", }, Object { "loc": Object { "end": Object { - "column": 17, - "line": 2, + "column": 24, + "line": 1, }, "start": Object { - "column": 11, - "line": 2, + "column": 20, + "line": 1, }, }, "range": Array [ - 42, - 48, + 20, + 24, ], "type": "Identifier", - "value": "number", + "value": "from", }, Object { "loc": Object { "end": Object { - "column": 1, - "line": 3, + "column": 30, + "line": 1, }, "start": Object { - "column": 0, - "line": 3, + "column": 25, + "line": 1, }, }, "range": Array [ - 49, - 50, + 25, + 30, ], - "type": "Punctuator", - "value": "}", + "type": "String", + "value": "'bar'", }, Object { "loc": Object { "end": Object { - "column": 2, - "line": 3, + "column": 31, + "line": 1, }, "start": Object { - "column": 1, - "line": 3, + "column": 30, + "line": 1, }, }, "range": Array [ - 50, - 51, + 30, + 31, ], "type": "Punctuator", "value": ";", @@ -47440,173 +47543,107 @@ Object { } `; -exports[`typescript fixtures/basics/export-type-function-declaration.src 1`] = ` +exports[`typescript fixtures/basics/export-type-from-as.src 1`] = ` Object { "body": Array [ Object { - "declaration": Object { - "id": Object { - "loc": Object { - "end": Object { - "column": 24, - "line": 1, - }, - "start": Object { - "column": 12, - "line": 1, - }, - }, - "name": "TestCallback", - "range": Array [ - 12, - 24, - ], - "type": "Identifier", + "declaration": null, + "exportKind": "type", + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, }, + }, + "range": Array [ + 0, + 34, + ], + "source": Object { "loc": Object { "end": Object { - "column": 47, + "column": 33, "line": 1, }, "start": Object { - "column": 7, + "column": 28, "line": 1, }, }, "range": Array [ - 7, - 47, + 28, + 33, ], - "type": "TSTypeAliasDeclaration", - "typeAnnotation": Object { + "raw": "'./a'", + "type": "Literal", + "value": "./a", + }, + "specifiers": Array [ + Object { + "exported": Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "name": "C", + "range": Array [ + 19, + 20, + ], + "type": "Identifier", + }, "loc": Object { "end": Object { - "column": 46, + "column": 20, "line": 1, }, "start": Object { - "column": 27, + "column": 14, "line": 1, }, }, - "params": Array [ - Object { - "loc": Object { - "end": Object { - "column": 37, - "line": 1, - }, - "start": Object { - "column": 28, - "line": 1, - }, - }, - "name": "a", - "range": Array [ - 28, - 37, - ], - "type": "Identifier", - "typeAnnotation": Object { - "loc": Object { - "end": Object { - "column": 37, - "line": 1, - }, - "start": Object { - "column": 29, - "line": 1, - }, - }, - "range": Array [ - 29, - 37, - ], - "type": "TSTypeAnnotation", - "typeAnnotation": Object { - "loc": Object { - "end": Object { - "column": 37, - "line": 1, - }, - "start": Object { - "column": 31, - "line": 1, - }, - }, - "range": Array [ - 31, - 37, - ], - "type": "TSNumberKeyword", - }, - }, - }, - ], - "range": Array [ - 27, - 46, - ], - "returnType": Object { + "local": Object { "loc": Object { "end": Object { - "column": 46, + "column": 15, "line": 1, }, "start": Object { - "column": 39, + "column": 14, "line": 1, }, }, + "name": "B", "range": Array [ - 39, - 46, + 14, + 15, ], - "type": "TSTypeAnnotation", - "typeAnnotation": Object { - "loc": Object { - "end": Object { - "column": 46, - "line": 1, - }, - "start": Object { - "column": 42, - "line": 1, - }, - }, - "range": Array [ - 42, - 46, - ], - "type": "TSVoidKeyword", - }, + "type": "Identifier", }, - "type": "TSFunctionType", - }, - }, - "loc": Object { - "end": Object { - "column": 47, - "line": 1, - }, - "start": Object { - "column": 0, - "line": 1, + "range": Array [ + 14, + 20, + ], + "type": "ExportSpecifier", }, - }, - "range": Array [ - 0, - 47, ], - "source": null, - "specifiers": Array [], "type": "ExportNamedDeclaration", }, ], "loc": Object { "end": Object { - "column": 47, - "line": 1, + "column": 0, + "line": 2, }, "start": Object { "column": 0, @@ -47615,7 +47652,7 @@ Object { }, "range": Array [ 0, - 47, + 35, ], "sourceType": "module", "tokens": Array [ @@ -47658,7 +47695,7 @@ Object { Object { "loc": Object { "end": Object { - "column": 24, + "column": 13, "line": 1, }, "start": Object { @@ -47668,181 +47705,315 @@ Object { }, "range": Array [ 12, - 24, + 13, ], - "type": "Identifier", - "value": "TestCallback", + "type": "Punctuator", + "value": "{", }, Object { "loc": Object { "end": Object { - "column": 26, + "column": 15, "line": 1, }, "start": Object { - "column": 25, + "column": 14, "line": 1, }, }, "range": Array [ - 25, - 26, + 14, + 15, ], - "type": "Punctuator", - "value": "=", + "type": "Identifier", + "value": "B", }, Object { "loc": Object { "end": Object { - "column": 28, + "column": 18, "line": 1, }, "start": Object { - "column": 27, + "column": 16, "line": 1, }, }, "range": Array [ - 27, - 28, + 16, + 18, ], - "type": "Punctuator", - "value": "(", + "type": "Identifier", + "value": "as", }, Object { "loc": Object { "end": Object { - "column": 29, + "column": 20, "line": 1, }, "start": Object { - "column": 28, + "column": 19, "line": 1, }, }, "range": Array [ - 28, - 29, + 19, + 20, ], "type": "Identifier", - "value": "a", + "value": "C", }, Object { "loc": Object { "end": Object { - "column": 30, + "column": 22, "line": 1, }, "start": Object { - "column": 29, + "column": 21, "line": 1, }, }, "range": Array [ - 29, - 30, + 21, + 22, ], "type": "Punctuator", - "value": ":", + "value": "}", }, Object { "loc": Object { "end": Object { - "column": 37, + "column": 27, "line": 1, }, "start": Object { - "column": 31, + "column": 23, "line": 1, }, }, "range": Array [ - 31, - 37, + 23, + 27, ], "type": "Identifier", - "value": "number", + "value": "from", }, Object { "loc": Object { "end": Object { - "column": 38, + "column": 33, "line": 1, }, "start": Object { - "column": 37, + "column": 28, "line": 1, }, }, "range": Array [ - 37, - 38, + 28, + 33, ], - "type": "Punctuator", - "value": ")", + "type": "String", + "value": "'./a'", }, Object { "loc": Object { "end": Object { - "column": 41, + "column": 34, "line": 1, }, "start": Object { - "column": 39, + "column": 33, "line": 1, }, }, "range": Array [ - 39, - 41, + 33, + 34, ], "type": "Punctuator", - "value": "=>", + "value": ";", }, + ], + "type": "Program", +} +`; + +exports[`typescript fixtures/basics/export-type-star-from.src 1`] = ` +Object { + "body": Array [ Object { + "exportKind": "type", "loc": Object { "end": Object { - "column": 46, + "column": 25, "line": 1, }, "start": Object { - "column": 42, + "column": 0, "line": 1, }, }, "range": Array [ - 42, - 46, + 0, + 25, + ], + "source": Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "range": Array [ + 19, + 24, + ], + "raw": "'bar'", + "type": "Literal", + "value": "bar", + }, + "type": "ExportAllDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 26, + ], + "sourceType": "module", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 6, ], "type": "Keyword", - "value": "void", + "value": "export", }, Object { "loc": Object { "end": Object { - "column": 47, + "column": 11, "line": 1, }, "start": Object { - "column": 46, + "column": 7, "line": 1, }, }, "range": Array [ - 46, - 47, + 7, + 11, ], - "type": "Punctuator", - "value": ";", + "type": "Identifier", + "value": "type", }, - ], - "type": "Program", -} -`; - -exports[`typescript fixtures/basics/function-anonymus-with-type-parameters.src 1`] = ` -Object { - "body": Array [ + Object { + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "range": Array [ + 12, + 13, + ], + "type": "Punctuator", + "value": "*", + }, + Object { + "loc": Object { + "end": Object { + "column": 18, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "range": Array [ + 14, + 18, + ], + "type": "Identifier", + "value": "from", + }, + Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "range": Array [ + 19, + 24, + ], + "type": "String", + "value": "'bar'", + }, + Object { + "loc": Object { + "end": Object { + "column": 25, + "line": 1, + }, + "start": Object { + "column": 24, + "line": 1, + }, + }, + "range": Array [ + 24, + 25, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; + +exports[`typescript fixtures/basics/function-anonymus-with-type-parameters.src 1`] = ` +Object { + "body": Array [ Object { "declarations": Array [ Object { @@ -48909,6 +49080,7 @@ Object { }, "type": "TSDeclareFunction", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 37, @@ -49054,6 +49226,7 @@ Object { }, "type": "TSDeclareFunction", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 37, @@ -49325,6 +49498,7 @@ Object { }, "type": "FunctionDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 1, @@ -56129,31 +56303,14 @@ Object { } `; -exports[`typescript fixtures/basics/import-type.src 1`] = ` +exports[`typescript fixtures/basics/import-type-default.src 1`] = ` Object { "body": Array [ Object { - "id": Object { - "loc": Object { - "end": Object { - "column": 6, - "line": 1, - }, - "start": Object { - "column": 5, - "line": 1, - }, - }, - "name": "A", - "range": Array [ - 5, - 6, - ], - "type": "Identifier", - }, + "importKind": "type", "loc": Object { "end": Object { - "column": 28, + "column": 27, "line": 1, }, "start": Object { @@ -56163,232 +56320,71 @@ Object { }, "range": Array [ 0, - 28, + 27, ], - "type": "TSTypeAliasDeclaration", - "typeAnnotation": Object { - "isTypeOf": true, + "source": Object { "loc": Object { "end": Object { - "column": 27, + "column": 26, "line": 1, }, "start": Object { - "column": 9, + "column": 21, "line": 1, }, }, - "parameter": Object { - "literal": Object { - "loc": Object { - "end": Object { - "column": 26, - "line": 1, - }, - "start": Object { - "column": 23, - "line": 1, - }, - }, - "range": Array [ - 23, - 26, - ], - "raw": "'A'", - "type": "Literal", - "value": "A", - }, + "range": Array [ + 21, + 26, + ], + "raw": "'bar'", + "type": "Literal", + "value": "bar", + }, + "specifiers": Array [ + Object { "loc": Object { "end": Object { - "column": 26, + "column": 15, "line": 1, }, "start": Object { - "column": 23, + "column": 7, "line": 1, }, }, - "range": Array [ - 23, - 26, - ], - "type": "TSLiteralType", - }, - "qualifier": null, - "range": Array [ - 9, - 27, - ], - "type": "TSImportType", - "typeParameters": null, - }, - }, - Object { - "id": Object { - "loc": Object { - "end": Object { - "column": 6, - "line": 2, - }, - "start": Object { - "column": 5, - "line": 2, - }, - }, - "name": "B", - "range": Array [ - 34, - 35, - ], - "type": "Identifier", - }, - "loc": Object { - "end": Object { - "column": 26, - "line": 2, - }, - "start": Object { - "column": 0, - "line": 2, - }, - }, - "range": Array [ - 29, - 55, - ], - "type": "TSTypeAliasDeclaration", - "typeAnnotation": Object { - "isTypeOf": false, - "loc": Object { - "end": Object { - "column": 25, - "line": 2, - }, - "start": Object { - "column": 9, - "line": 2, - }, - }, - "parameter": Object { - "literal": Object { + "local": Object { "loc": Object { "end": Object { - "column": 19, - "line": 2, + "column": 15, + "line": 1, }, "start": Object { - "column": 16, - "line": 2, + "column": 12, + "line": 1, }, }, + "name": "foo", "range": Array [ - 45, - 48, + 12, + 15, ], - "raw": "\\"B\\"", - "type": "Literal", - "value": "B", - }, - "loc": Object { - "end": Object { - "column": 19, - "line": 2, - }, - "start": Object { - "column": 16, - "line": 2, - }, - }, - "range": Array [ - 45, - 48, - ], - "type": "TSLiteralType", - }, - "qualifier": Object { - "loc": Object { - "end": Object { - "column": 22, - "line": 2, - }, - "start": Object { - "column": 21, - "line": 2, - }, - }, - "name": "X", - "range": Array [ - 50, - 51, - ], - "type": "Identifier", - }, - "range": Array [ - 38, - 54, - ], - "type": "TSImportType", - "typeParameters": Object { - "loc": Object { - "end": Object { - "column": 25, - "line": 2, - }, - "start": Object { - "column": 22, - "line": 2, - }, + "type": "Identifier", }, - "params": Array [ - Object { - "loc": Object { - "end": Object { - "column": 24, - "line": 2, - }, - "start": Object { - "column": 23, - "line": 2, - }, - }, - "range": Array [ - 52, - 53, - ], - "type": "TSTypeReference", - "typeName": Object { - "loc": Object { - "end": Object { - "column": 24, - "line": 2, - }, - "start": Object { - "column": 23, - "line": 2, - }, - }, - "name": "Y", - "range": Array [ - 52, - 53, - ], - "type": "Identifier", - }, - }, - ], "range": Array [ - 51, - 54, + 7, + 15, ], - "type": "TSTypeParameterInstantiation", + "type": "ImportDefaultSpecifier", }, - }, + ], + "type": "ImportDeclaration", }, ], "loc": Object { "end": Object { "column": 0, - "line": 3, + "line": 2, }, "start": Object { "column": 0, @@ -56397,14 +56393,14 @@ Object { }, "range": Array [ 0, - 56, + 28, ], - "sourceType": "script", + "sourceType": "module", "tokens": Array [ Object { "loc": Object { "end": Object { - "column": 4, + "column": 6, "line": 1, }, "start": Object { @@ -56414,33 +56410,15 @@ Object { }, "range": Array [ 0, - 4, - ], - "type": "Identifier", - "value": "type", - }, - Object { - "loc": Object { - "end": Object { - "column": 6, - "line": 1, - }, - "start": Object { - "column": 5, - "line": 1, - }, - }, - "range": Array [ - 5, 6, ], - "type": "Identifier", - "value": "A", + "type": "Keyword", + "value": "import", }, Object { "loc": Object { "end": Object { - "column": 8, + "column": 11, "line": 1, }, "start": Object { @@ -56450,10 +56428,10 @@ Object { }, "range": Array [ 7, - 8, + 11, ], - "type": "Punctuator", - "value": "=", + "type": "Identifier", + "value": "type", }, Object { "loc": Object { @@ -56462,21 +56440,21 @@ Object { "line": 1, }, "start": Object { - "column": 9, + "column": 12, "line": 1, }, }, "range": Array [ - 9, + 12, 15, ], - "type": "Keyword", - "value": "typeof", + "type": "Identifier", + "value": "foo", }, Object { "loc": Object { "end": Object { - "column": 22, + "column": 20, "line": 1, }, "start": Object { @@ -56486,28 +56464,10 @@ Object { }, "range": Array [ 16, - 22, - ], - "type": "Keyword", - "value": "import", - }, - Object { - "loc": Object { - "end": Object { - "column": 23, - "line": 1, - }, - "start": Object { - "column": 22, - "line": 1, - }, - }, - "range": Array [ - 22, - 23, + 20, ], - "type": "Punctuator", - "value": "(", + "type": "Identifier", + "value": "from", }, Object { "loc": Object { @@ -56516,16 +56476,16 @@ Object { "line": 1, }, "start": Object { - "column": 23, + "column": 21, "line": 1, }, }, "range": Array [ - 23, + 21, 26, ], "type": "String", - "value": "'A'", + "value": "'bar'", }, Object { "loc": Object { @@ -56543,30 +56503,21 @@ Object { 27, ], "type": "Punctuator", - "value": ")", - }, - Object { - "loc": Object { - "end": Object { - "column": 28, - "line": 1, - }, - "start": Object { - "column": 27, - "line": 1, - }, - }, - "range": Array [ - 27, - 28, - ], - "type": "Punctuator", "value": ";", }, + ], + "type": "Program", +} +`; + +exports[`typescript fixtures/basics/import-type-empty.src 1`] = ` +Object { + "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { - "column": 4, + "column": 25, "line": 2, }, "start": Object { @@ -56575,62 +56526,98 @@ Object { }, }, "range": Array [ - 29, - 33, + 55, + 80, ], - "type": "Identifier", - "value": "type", - }, - Object { - "loc": Object { - "end": Object { - "column": 6, - "line": 2, - }, - "start": Object { - "column": 5, - "line": 2, + "source": Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 2, + }, + "start": Object { + "column": 17, + "line": 2, + }, }, + "range": Array [ + 72, + 79, + ], + "raw": "'./foo'", + "type": "Literal", + "value": "./foo", }, - "range": Array [ - 34, - 35, - ], - "type": "Identifier", - "value": "B", - }, - Object { - "loc": Object { - "end": Object { - "column": 8, - "line": 2, - }, - "start": Object { - "column": 7, - "line": 2, + "specifiers": Array [ + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 2, + }, + "start": Object { + "column": 7, + "line": 2, + }, + }, + "local": Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 2, + }, + "start": Object { + "column": 7, + "line": 2, + }, + }, + "name": "type", + "range": Array [ + 62, + 66, + ], + "type": "Identifier", + }, + "range": Array [ + 62, + 66, + ], + "type": "ImportDefaultSpecifier", }, - }, - "range": Array [ - 36, - 37, ], - "type": "Punctuator", - "value": "=", + "type": "ImportDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 3, + }, + "start": Object { + "column": 0, + "line": 2, }, + }, + "range": Array [ + 55, + 81, + ], + "sourceType": "module", + "tokens": Array [ Object { "loc": Object { "end": Object { - "column": 15, + "column": 6, "line": 2, }, "start": Object { - "column": 9, + "column": 0, "line": 2, }, }, "range": Array [ - 38, - 44, + 55, + 61, ], "type": "Keyword", "value": "import", @@ -56638,110 +56625,38 @@ Object { Object { "loc": Object { "end": Object { - "column": 16, + "column": 11, "line": 2, }, "start": Object { - "column": 15, + "column": 7, "line": 2, }, }, "range": Array [ - 44, - 45, + 62, + 66, ], - "type": "Punctuator", - "value": "(", + "type": "Identifier", + "value": "type", }, Object { "loc": Object { "end": Object { - "column": 19, - "line": 2, - }, - "start": Object { "column": 16, "line": 2, }, - }, - "range": Array [ - 45, - 48, - ], - "type": "String", - "value": "\\"B\\"", - }, - Object { - "loc": Object { - "end": Object { - "column": 20, - "line": 2, - }, - "start": Object { - "column": 19, - "line": 2, - }, - }, - "range": Array [ - 48, - 49, - ], - "type": "Punctuator", - "value": ")", - }, - Object { - "loc": Object { - "end": Object { - "column": 21, - "line": 2, - }, - "start": Object { - "column": 20, - "line": 2, - }, - }, - "range": Array [ - 49, - 50, - ], - "type": "Punctuator", - "value": ".", - }, - Object { - "loc": Object { - "end": Object { - "column": 22, - "line": 2, - }, "start": Object { - "column": 21, + "column": 12, "line": 2, }, }, "range": Array [ - 50, - 51, + 67, + 71, ], "type": "Identifier", - "value": "X", - }, - Object { - "loc": Object { - "end": Object { - "column": 23, - "line": 2, - }, - "start": Object { - "column": 22, - "line": 2, - }, - }, - "range": Array [ - 51, - 52, - ], - "type": "Punctuator", - "value": "<", + "value": "from", }, Object { "loc": Object { @@ -56750,16 +56665,16 @@ Object { "line": 2, }, "start": Object { - "column": 23, + "column": 17, "line": 2, }, }, "range": Array [ - 52, - 53, + 72, + 79, ], - "type": "Identifier", - "value": "Y", + "type": "String", + "value": "'./foo'", }, Object { "loc": Object { @@ -56773,26 +56688,8 @@ Object { }, }, "range": Array [ - 53, - 54, - ], - "type": "Punctuator", - "value": ">", - }, - Object { - "loc": Object { - "end": Object { - "column": 26, - "line": 2, - }, - "start": Object { - "column": 25, - "line": 2, - }, - }, - "range": Array [ - 54, - 55, + 79, + 80, ], "type": "Punctuator", "value": ";", @@ -56802,31 +56699,14 @@ Object { } `; -exports[`typescript fixtures/basics/import-type-with-type-parameters-in-type-reference.src 1`] = ` +exports[`typescript fixtures/basics/import-type-error.src 1`] = ` Object { "body": Array [ Object { - "id": Object { - "loc": Object { - "end": Object { - "column": 6, - "line": 1, - }, - "start": Object { - "column": 5, - "line": 1, - }, - }, - "name": "X", - "range": Array [ - 5, - 6, - ], - "type": "Identifier", - }, + "importKind": "type", "loc": Object { "end": Object { - "column": 30, + "column": 36, "line": 1, }, "start": Object { @@ -56836,171 +56716,118 @@ Object { }, "range": Array [ 0, - 30, + 36, ], - "type": "TSTypeAliasDeclaration", - "typeAnnotation": Object { + "source": Object { "loc": Object { "end": Object { - "column": 29, + "column": 35, "line": 1, }, "start": Object { - "column": 9, + "column": 30, "line": 1, }, }, "range": Array [ - 9, - 29, + 30, + 35, ], - "type": "TSTypeReference", - "typeName": Object { + "raw": "'bar'", + "type": "Literal", + "value": "bar", + }, + "specifiers": Array [ + Object { "loc": Object { "end": Object { - "column": 10, + "column": 15, "line": 1, }, "start": Object { - "column": 9, + "column": 7, "line": 1, }, }, - "name": "A", + "local": Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "name": "foo", + "range": Array [ + 12, + 15, + ], + "type": "Identifier", + }, "range": Array [ - 9, - 10, + 7, + 15, ], - "type": "Identifier", + "type": "ImportDefaultSpecifier", }, - "typeParameters": Object { + Object { + "imported": Object { + "loc": Object { + "end": Object { + "column": 22, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "name": "bar", + "range": Array [ + 19, + 22, + ], + "type": "Identifier", + }, "loc": Object { "end": Object { - "column": 29, + "column": 22, "line": 1, }, "start": Object { - "column": 10, + "column": 19, "line": 1, }, }, - "params": Array [ - Object { - "isTypeOf": false, - "loc": Object { - "end": Object { - "column": 28, - "line": 1, - }, - "start": Object { - "column": 11, - "line": 1, - }, - }, - "parameter": Object { - "literal": Object { - "loc": Object { - "end": Object { - "column": 20, - "line": 1, - }, - "start": Object { - "column": 18, - "line": 1, - }, - }, - "range": Array [ - 18, - 20, - ], - "raw": "\\"\\"", - "type": "Literal", - "value": "", - }, - "loc": Object { - "end": Object { - "column": 20, - "line": 1, - }, - "start": Object { - "column": 18, - "line": 1, - }, - }, - "range": Array [ - 18, - 20, - ], - "type": "TSLiteralType", - }, - "qualifier": Object { - "loc": Object { - "end": Object { - "column": 23, - "line": 1, - }, - "start": Object { - "column": 22, - "line": 1, - }, - }, - "name": "B", - "range": Array [ - 22, - 23, - ], - "type": "Identifier", + "local": Object { + "loc": Object { + "end": Object { + "column": 22, + "line": 1, }, - "range": Array [ - 11, - 28, - ], - "type": "TSImportType", - "typeParameters": Object { - "loc": Object { - "end": Object { - "column": 28, - "line": 1, - }, - "start": Object { - "column": 23, - "line": 1, - }, - }, - "params": Array [ - Object { - "loc": Object { - "end": Object { - "column": 27, - "line": 1, - }, - "start": Object { - "column": 24, - "line": 1, - }, - }, - "range": Array [ - 24, - 27, - ], - "type": "TSAnyKeyword", - }, - ], - "range": Array [ - 23, - 28, - ], - "type": "TSTypeParameterInstantiation", + "start": Object { + "column": 19, + "line": 1, }, }, - ], + "name": "bar", + "range": Array [ + 19, + 22, + ], + "type": "Identifier", + }, "range": Array [ - 10, - 29, + 19, + 22, ], - "type": "TSTypeParameterInstantiation", + "type": "ImportSpecifier", }, - }, + ], + "type": "ImportDeclaration", }, ], "loc": Object { @@ -57015,14 +56842,14 @@ Object { }, "range": Array [ 0, - 31, + 37, ], - "sourceType": "script", + "sourceType": "module", "tokens": Array [ Object { "loc": Object { "end": Object { - "column": 4, + "column": 6, "line": 1, }, "start": Object { @@ -57032,33 +56859,15 @@ Object { }, "range": Array [ 0, - 4, - ], - "type": "Identifier", - "value": "type", - }, - Object { - "loc": Object { - "end": Object { - "column": 6, - "line": 1, - }, - "start": Object { - "column": 5, - "line": 1, - }, - }, - "range": Array [ - 5, 6, ], - "type": "Identifier", - "value": "X", + "type": "Keyword", + "value": "import", }, Object { "loc": Object { "end": Object { - "column": 8, + "column": 11, "line": 1, }, "start": Object { @@ -57068,64 +56877,46 @@ Object { }, "range": Array [ 7, - 8, + 11, ], - "type": "Punctuator", - "value": "=", + "type": "Identifier", + "value": "type", }, Object { "loc": Object { "end": Object { - "column": 10, + "column": 15, "line": 1, }, "start": Object { - "column": 9, + "column": 12, "line": 1, }, }, "range": Array [ - 9, - 10, + 12, + 15, ], "type": "Identifier", - "value": "A", + "value": "foo", }, Object { "loc": Object { "end": Object { - "column": 11, + "column": 16, "line": 1, }, "start": Object { - "column": 10, + "column": 15, "line": 1, }, }, "range": Array [ - 10, - 11, + 15, + 16, ], "type": "Punctuator", - "value": "<", - }, - Object { - "loc": Object { - "end": Object { - "column": 17, - "line": 1, - }, - "start": Object { - "column": 11, - "line": 1, - }, - }, - "range": Array [ - 11, - 17, - ], - "type": "Keyword", - "value": "import", + "value": ",", }, Object { "loc": Object { @@ -57143,166 +56934,984 @@ Object { 18, ], "type": "Punctuator", - "value": "(", + "value": "{", }, Object { "loc": Object { "end": Object { - "column": 20, + "column": 22, "line": 1, }, "start": Object { - "column": 18, + "column": 19, "line": 1, }, }, "range": Array [ - 18, - 20, + 19, + 22, ], - "type": "String", - "value": "\\"\\"", + "type": "Identifier", + "value": "bar", }, Object { "loc": Object { "end": Object { - "column": 21, + "column": 24, "line": 1, }, "start": Object { - "column": 20, + "column": 23, "line": 1, }, }, "range": Array [ - 20, - 21, + 23, + 24, ], "type": "Punctuator", - "value": ")", + "value": "}", }, Object { "loc": Object { "end": Object { - "column": 22, + "column": 29, "line": 1, }, "start": Object { - "column": 21, + "column": 25, "line": 1, }, }, "range": Array [ - 21, - 22, + 25, + 29, ], - "type": "Punctuator", - "value": ".", + "type": "Identifier", + "value": "from", }, Object { "loc": Object { "end": Object { - "column": 23, + "column": 35, "line": 1, }, "start": Object { - "column": 22, + "column": 30, "line": 1, }, }, "range": Array [ - 22, - 23, + 30, + 35, ], - "type": "Identifier", - "value": "B", + "type": "String", + "value": "'bar'", }, Object { "loc": Object { "end": Object { - "column": 24, + "column": 36, "line": 1, }, "start": Object { - "column": 23, + "column": 35, "line": 1, }, }, "range": Array [ - 23, - 24, + 35, + 36, ], "type": "Punctuator", - "value": "<", + "value": ";", }, + ], + "type": "Program", +} +`; + +exports[`typescript fixtures/basics/import-type-named.src 1`] = ` +Object { + "body": Array [ Object { + "importKind": "type", "loc": Object { "end": Object { - "column": 27, + "column": 36, "line": 1, }, "start": Object { - "column": 24, + "column": 0, "line": 1, }, }, "range": Array [ - 24, - 27, + 0, + 36, + ], + "source": Object { + "loc": Object { + "end": Object { + "column": 35, + "line": 1, + }, + "start": Object { + "column": 30, + "line": 1, + }, + }, + "range": Array [ + 30, + 35, + ], + "raw": "'baz'", + "type": "Literal", + "value": "baz", + }, + "specifiers": Array [ + Object { + "imported": Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "name": "foo", + "range": Array [ + 14, + 17, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "local": Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "name": "foo", + "range": Array [ + 14, + 17, + ], + "type": "Identifier", + }, + "range": Array [ + 14, + 17, + ], + "type": "ImportSpecifier", + }, + Object { + "imported": Object { + "loc": Object { + "end": Object { + "column": 22, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "name": "bar", + "range": Array [ + 19, + 22, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 22, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "local": Object { + "loc": Object { + "end": Object { + "column": 22, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "name": "bar", + "range": Array [ + 19, + 22, + ], + "type": "Identifier", + }, + "range": Array [ + 19, + 22, + ], + "type": "ImportSpecifier", + }, + ], + "type": "ImportDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 37, + ], + "sourceType": "module", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 6, + ], + "type": "Keyword", + "value": "import", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 11, ], "type": "Identifier", - "value": "any", + "value": "type", }, Object { "loc": Object { "end": Object { - "column": 28, + "column": 13, "line": 1, }, "start": Object { - "column": 27, + "column": 12, "line": 1, }, }, "range": Array [ - 27, - 28, + 12, + 13, ], "type": "Punctuator", - "value": ">", + "value": "{", }, Object { "loc": Object { "end": Object { - "column": 29, + "column": 17, "line": 1, }, "start": Object { - "column": 28, + "column": 14, "line": 1, }, }, "range": Array [ - 28, - 29, + 14, + 17, + ], + "type": "Identifier", + "value": "foo", + }, + Object { + "loc": Object { + "end": Object { + "column": 18, + "line": 1, + }, + "start": Object { + "column": 17, + "line": 1, + }, + }, + "range": Array [ + 17, + 18, ], "type": "Punctuator", - "value": ">", + "value": ",", }, Object { "loc": Object { "end": Object { - "column": 30, + "column": 22, + "line": 1, + }, + "start": Object { + "column": 19, + "line": 1, + }, + }, + "range": Array [ + 19, + 22, + ], + "type": "Identifier", + "value": "bar", + }, + Object { + "loc": Object { + "end": Object { + "column": 24, "line": 1, }, "start": Object { + "column": 23, + "line": 1, + }, + }, + "range": Array [ + 23, + 24, + ], + "type": "Punctuator", + "value": "}", + }, + Object { + "loc": Object { + "end": Object { "column": 29, "line": 1, }, + "start": Object { + "column": 25, + "line": 1, + }, }, "range": Array [ + 25, 29, + ], + "type": "Identifier", + "value": "from", + }, + Object { + "loc": Object { + "end": Object { + "column": 35, + "line": 1, + }, + "start": Object { + "column": 30, + "line": 1, + }, + }, + "range": Array [ 30, + 35, + ], + "type": "String", + "value": "'baz'", + }, + Object { + "loc": Object { + "end": Object { + "column": 36, + "line": 1, + }, + "start": Object { + "column": 35, + "line": 1, + }, + }, + "range": Array [ + 35, + 36, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; + +exports[`typescript fixtures/basics/import-type-named-as.src 1`] = ` +Object { + "body": Array [ + Object { + "importKind": "type", + "loc": Object { + "end": Object { + "column": 38, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 38, + ], + "source": Object { + "loc": Object { + "end": Object { + "column": 37, + "line": 1, + }, + "start": Object { + "column": 32, + "line": 1, + }, + }, + "range": Array [ + 32, + 37, + ], + "raw": "'baz'", + "type": "Literal", + "value": "baz", + }, + "specifiers": Array [ + Object { + "imported": Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "name": "foo", + "range": Array [ + 14, + 17, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "local": Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 21, + "line": 1, + }, + }, + "name": "bar", + "range": Array [ + 21, + 24, + ], + "type": "Identifier", + }, + "range": Array [ + 14, + 24, + ], + "type": "ImportSpecifier", + }, + ], + "type": "ImportDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 39, + ], + "sourceType": "module", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 6, + ], + "type": "Keyword", + "value": "import", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 11, + ], + "type": "Identifier", + "value": "type", + }, + Object { + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "range": Array [ + 12, + 13, + ], + "type": "Punctuator", + "value": "{", + }, + Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "range": Array [ + 14, + 17, + ], + "type": "Identifier", + "value": "foo", + }, + Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 18, + "line": 1, + }, + }, + "range": Array [ + 18, + 20, + ], + "type": "Identifier", + "value": "as", + }, + Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 21, + "line": 1, + }, + }, + "range": Array [ + 21, + 24, + ], + "type": "Identifier", + "value": "bar", + }, + Object { + "loc": Object { + "end": Object { + "column": 26, + "line": 1, + }, + "start": Object { + "column": 25, + "line": 1, + }, + }, + "range": Array [ + 25, + 26, + ], + "type": "Punctuator", + "value": "}", + }, + Object { + "loc": Object { + "end": Object { + "column": 31, + "line": 1, + }, + "start": Object { + "column": 27, + "line": 1, + }, + }, + "range": Array [ + 27, + 31, + ], + "type": "Identifier", + "value": "from", + }, + Object { + "loc": Object { + "end": Object { + "column": 37, + "line": 1, + }, + "start": Object { + "column": 32, + "line": 1, + }, + }, + "range": Array [ + 32, + 37, + ], + "type": "String", + "value": "'baz'", + }, + Object { + "loc": Object { + "end": Object { + "column": 38, + "line": 1, + }, + "start": Object { + "column": 37, + "line": 1, + }, + }, + "range": Array [ + 37, + 38, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; + +exports[`typescript fixtures/basics/import-type-star-as-ns.src 1`] = ` +Object { + "body": Array [ + Object { + "importKind": "type", + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 34, + ], + "source": Object { + "loc": Object { + "end": Object { + "column": 33, + "line": 1, + }, + "start": Object { + "column": 26, + "line": 1, + }, + }, + "range": Array [ + 26, + 33, + ], + "raw": "'./bar'", + "type": "Literal", + "value": "./bar", + }, + "specifiers": Array [ + Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "local": Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 17, + "line": 1, + }, + }, + "name": "foo", + "range": Array [ + 17, + 20, + ], + "type": "Identifier", + }, + "range": Array [ + 12, + 20, + ], + "type": "ImportNamespaceSpecifier", + }, + ], + "type": "ImportDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 35, + ], + "sourceType": "module", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 6, + ], + "type": "Keyword", + "value": "import", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 11, + ], + "type": "Identifier", + "value": "type", + }, + Object { + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "range": Array [ + 12, + 13, + ], + "type": "Punctuator", + "value": "*", + }, + Object { + "loc": Object { + "end": Object { + "column": 16, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "range": Array [ + 14, + 16, + ], + "type": "Identifier", + "value": "as", + }, + Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 17, + "line": 1, + }, + }, + "range": Array [ + 17, + 20, + ], + "type": "Identifier", + "value": "foo", + }, + Object { + "loc": Object { + "end": Object { + "column": 25, + "line": 1, + }, + "start": Object { + "column": 21, + "line": 1, + }, + }, + "range": Array [ + 21, + 25, + ], + "type": "Identifier", + "value": "from", + }, + Object { + "loc": Object { + "end": Object { + "column": 33, + "line": 1, + }, + "start": Object { + "column": 26, + "line": 1, + }, + }, + "range": Array [ + 26, + 33, + ], + "type": "String", + "value": "'./bar'", + }, + Object { + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 33, + "line": 1, + }, + }, + "range": Array [ + 33, + 34, ], "type": "Punctuator", "value": ";", @@ -67252,6 +67861,7 @@ Object { "type": "BlockStatement", }, Object { + "importKind": "value", "loc": Object { "end": Object { "column": 21, @@ -97485,6 +98095,1033 @@ Object { } `; +exports[`typescript fixtures/basics/type-alias-declaration-export.src 1`] = ` +Object { + "body": Array [ + Object { + "declaration": Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 21, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "name": "TestAlias", + "range": Array [ + 12, + 21, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 40, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 40, + ], + "type": "TSTypeAliasDeclaration", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 39, + "line": 1, + }, + "start": Object { + "column": 24, + "line": 1, + }, + }, + "range": Array [ + 24, + 39, + ], + "type": "TSUnionType", + "types": Array [ + Object { + "loc": Object { + "end": Object { + "column": 30, + "line": 1, + }, + "start": Object { + "column": 24, + "line": 1, + }, + }, + "range": Array [ + 24, + 30, + ], + "type": "TSStringKeyword", + }, + Object { + "loc": Object { + "end": Object { + "column": 39, + "line": 1, + }, + "start": Object { + "column": 33, + "line": 1, + }, + }, + "range": Array [ + 33, + 39, + ], + "type": "TSNumberKeyword", + }, + ], + }, + }, + "exportKind": "type", + "loc": Object { + "end": Object { + "column": 40, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 40, + ], + "source": null, + "specifiers": Array [], + "type": "ExportNamedDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 40, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 40, + ], + "sourceType": "module", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 6, + ], + "type": "Keyword", + "value": "export", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 11, + ], + "type": "Identifier", + "value": "type", + }, + Object { + "loc": Object { + "end": Object { + "column": 21, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "range": Array [ + 12, + 21, + ], + "type": "Identifier", + "value": "TestAlias", + }, + Object { + "loc": Object { + "end": Object { + "column": 23, + "line": 1, + }, + "start": Object { + "column": 22, + "line": 1, + }, + }, + "range": Array [ + 22, + 23, + ], + "type": "Punctuator", + "value": "=", + }, + Object { + "loc": Object { + "end": Object { + "column": 30, + "line": 1, + }, + "start": Object { + "column": 24, + "line": 1, + }, + }, + "range": Array [ + 24, + 30, + ], + "type": "Identifier", + "value": "string", + }, + Object { + "loc": Object { + "end": Object { + "column": 32, + "line": 1, + }, + "start": Object { + "column": 31, + "line": 1, + }, + }, + "range": Array [ + 31, + 32, + ], + "type": "Punctuator", + "value": "|", + }, + Object { + "loc": Object { + "end": Object { + "column": 39, + "line": 1, + }, + "start": Object { + "column": 33, + "line": 1, + }, + }, + "range": Array [ + 33, + 39, + ], + "type": "Identifier", + "value": "number", + }, + Object { + "loc": Object { + "end": Object { + "column": 40, + "line": 1, + }, + "start": Object { + "column": 39, + "line": 1, + }, + }, + "range": Array [ + 39, + 40, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; + +exports[`typescript fixtures/basics/type-alias-declaration-export-function-type.src 1`] = ` +Object { + "body": Array [ + Object { + "declaration": Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "name": "TestCallback", + "range": Array [ + 12, + 24, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 47, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 47, + ], + "type": "TSTypeAliasDeclaration", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 46, + "line": 1, + }, + "start": Object { + "column": 27, + "line": 1, + }, + }, + "params": Array [ + Object { + "loc": Object { + "end": Object { + "column": 37, + "line": 1, + }, + "start": Object { + "column": 28, + "line": 1, + }, + }, + "name": "a", + "range": Array [ + 28, + 37, + ], + "type": "Identifier", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 37, + "line": 1, + }, + "start": Object { + "column": 29, + "line": 1, + }, + }, + "range": Array [ + 29, + 37, + ], + "type": "TSTypeAnnotation", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 37, + "line": 1, + }, + "start": Object { + "column": 31, + "line": 1, + }, + }, + "range": Array [ + 31, + 37, + ], + "type": "TSNumberKeyword", + }, + }, + }, + ], + "range": Array [ + 27, + 46, + ], + "returnType": Object { + "loc": Object { + "end": Object { + "column": 46, + "line": 1, + }, + "start": Object { + "column": 39, + "line": 1, + }, + }, + "range": Array [ + 39, + 46, + ], + "type": "TSTypeAnnotation", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 46, + "line": 1, + }, + "start": Object { + "column": 42, + "line": 1, + }, + }, + "range": Array [ + 42, + 46, + ], + "type": "TSVoidKeyword", + }, + }, + "type": "TSFunctionType", + }, + }, + "exportKind": "type", + "loc": Object { + "end": Object { + "column": 47, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 47, + ], + "source": null, + "specifiers": Array [], + "type": "ExportNamedDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 47, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 47, + ], + "sourceType": "module", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 6, + ], + "type": "Keyword", + "value": "export", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 11, + ], + "type": "Identifier", + "value": "type", + }, + Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "range": Array [ + 12, + 24, + ], + "type": "Identifier", + "value": "TestCallback", + }, + Object { + "loc": Object { + "end": Object { + "column": 26, + "line": 1, + }, + "start": Object { + "column": 25, + "line": 1, + }, + }, + "range": Array [ + 25, + 26, + ], + "type": "Punctuator", + "value": "=", + }, + Object { + "loc": Object { + "end": Object { + "column": 28, + "line": 1, + }, + "start": Object { + "column": 27, + "line": 1, + }, + }, + "range": Array [ + 27, + 28, + ], + "type": "Punctuator", + "value": "(", + }, + Object { + "loc": Object { + "end": Object { + "column": 29, + "line": 1, + }, + "start": Object { + "column": 28, + "line": 1, + }, + }, + "range": Array [ + 28, + 29, + ], + "type": "Identifier", + "value": "a", + }, + Object { + "loc": Object { + "end": Object { + "column": 30, + "line": 1, + }, + "start": Object { + "column": 29, + "line": 1, + }, + }, + "range": Array [ + 29, + 30, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 37, + "line": 1, + }, + "start": Object { + "column": 31, + "line": 1, + }, + }, + "range": Array [ + 31, + 37, + ], + "type": "Identifier", + "value": "number", + }, + Object { + "loc": Object { + "end": Object { + "column": 38, + "line": 1, + }, + "start": Object { + "column": 37, + "line": 1, + }, + }, + "range": Array [ + 37, + 38, + ], + "type": "Punctuator", + "value": ")", + }, + Object { + "loc": Object { + "end": Object { + "column": 41, + "line": 1, + }, + "start": Object { + "column": 39, + "line": 1, + }, + }, + "range": Array [ + 39, + 41, + ], + "type": "Punctuator", + "value": "=>", + }, + Object { + "loc": Object { + "end": Object { + "column": 46, + "line": 1, + }, + "start": Object { + "column": 42, + "line": 1, + }, + }, + "range": Array [ + 42, + 46, + ], + "type": "Keyword", + "value": "void", + }, + Object { + "loc": Object { + "end": Object { + "column": 47, + "line": 1, + }, + "start": Object { + "column": 46, + "line": 1, + }, + }, + "range": Array [ + 46, + 47, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; + +exports[`typescript fixtures/basics/type-alias-declaration-export-object-type.src 1`] = ` +Object { + "body": Array [ + Object { + "declaration": Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 26, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "name": "TestClassProps", + "range": Array [ + 12, + 26, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 2, + "line": 3, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 51, + ], + "type": "TSTypeAliasDeclaration", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 1, + "line": 3, + }, + "start": Object { + "column": 29, + "line": 1, + }, + }, + "members": Array [ + Object { + "computed": false, + "key": Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 2, + }, + "start": Object { + "column": 4, + "line": 2, + }, + }, + "name": "count", + "range": Array [ + 35, + 40, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 17, + "line": 2, + }, + "start": Object { + "column": 4, + "line": 2, + }, + }, + "range": Array [ + 35, + 48, + ], + "type": "TSPropertySignature", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 2, + }, + "start": Object { + "column": 9, + "line": 2, + }, + }, + "range": Array [ + 40, + 48, + ], + "type": "TSTypeAnnotation", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 2, + }, + "start": Object { + "column": 11, + "line": 2, + }, + }, + "range": Array [ + 42, + 48, + ], + "type": "TSNumberKeyword", + }, + }, + }, + ], + "range": Array [ + 29, + 50, + ], + "type": "TSTypeLiteral", + }, + }, + "exportKind": "type", + "loc": Object { + "end": Object { + "column": 2, + "line": 3, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 51, + ], + "source": null, + "specifiers": Array [], + "type": "ExportNamedDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 2, + "line": 3, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 51, + ], + "sourceType": "module", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 6, + ], + "type": "Keyword", + "value": "export", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 11, + ], + "type": "Identifier", + "value": "type", + }, + Object { + "loc": Object { + "end": Object { + "column": 26, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "range": Array [ + 12, + 26, + ], + "type": "Identifier", + "value": "TestClassProps", + }, + Object { + "loc": Object { + "end": Object { + "column": 28, + "line": 1, + }, + "start": Object { + "column": 27, + "line": 1, + }, + }, + "range": Array [ + 27, + 28, + ], + "type": "Punctuator", + "value": "=", + }, + Object { + "loc": Object { + "end": Object { + "column": 30, + "line": 1, + }, + "start": Object { + "column": 29, + "line": 1, + }, + }, + "range": Array [ + 29, + 30, + ], + "type": "Punctuator", + "value": "{", + }, + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 2, + }, + "start": Object { + "column": 4, + "line": 2, + }, + }, + "range": Array [ + 35, + 40, + ], + "type": "Identifier", + "value": "count", + }, + Object { + "loc": Object { + "end": Object { + "column": 10, + "line": 2, + }, + "start": Object { + "column": 9, + "line": 2, + }, + }, + "range": Array [ + 40, + 41, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 2, + }, + "start": Object { + "column": 11, + "line": 2, + }, + }, + "range": Array [ + 42, + 48, + ], + "type": "Identifier", + "value": "number", + }, + Object { + "loc": Object { + "end": Object { + "column": 1, + "line": 3, + }, + "start": Object { + "column": 0, + "line": 3, + }, + }, + "range": Array [ + 49, + 50, + ], + "type": "Punctuator", + "value": "}", + }, + Object { + "loc": Object { + "end": Object { + "column": 2, + "line": 3, + }, + "start": Object { + "column": 1, + "line": 3, + }, + }, + "range": Array [ + 50, + 51, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; + exports[`typescript fixtures/basics/type-alias-declaration-with-constrained-type-parameter.src 1`] = ` Object { "body": Array [ @@ -106358,6 +107995,1189 @@ Object { } `; +exports[`typescript fixtures/basics/type-import-type.src 1`] = ` +Object { + "body": Array [ + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "name": "A", + "range": Array [ + 5, + 6, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 28, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 28, + ], + "type": "TSTypeAliasDeclaration", + "typeAnnotation": Object { + "isTypeOf": true, + "loc": Object { + "end": Object { + "column": 27, + "line": 1, + }, + "start": Object { + "column": 9, + "line": 1, + }, + }, + "parameter": Object { + "literal": Object { + "loc": Object { + "end": Object { + "column": 26, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "range": Array [ + 23, + 26, + ], + "raw": "'A'", + "type": "Literal", + "value": "A", + }, + "loc": Object { + "end": Object { + "column": 26, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "range": Array [ + 23, + 26, + ], + "type": "TSLiteralType", + }, + "qualifier": null, + "range": Array [ + 9, + 27, + ], + "type": "TSImportType", + "typeParameters": null, + }, + }, + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 2, + }, + "start": Object { + "column": 5, + "line": 2, + }, + }, + "name": "B", + "range": Array [ + 34, + 35, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 26, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 2, + }, + }, + "range": Array [ + 29, + 55, + ], + "type": "TSTypeAliasDeclaration", + "typeAnnotation": Object { + "isTypeOf": false, + "loc": Object { + "end": Object { + "column": 25, + "line": 2, + }, + "start": Object { + "column": 9, + "line": 2, + }, + }, + "parameter": Object { + "literal": Object { + "loc": Object { + "end": Object { + "column": 19, + "line": 2, + }, + "start": Object { + "column": 16, + "line": 2, + }, + }, + "range": Array [ + 45, + 48, + ], + "raw": "\\"B\\"", + "type": "Literal", + "value": "B", + }, + "loc": Object { + "end": Object { + "column": 19, + "line": 2, + }, + "start": Object { + "column": 16, + "line": 2, + }, + }, + "range": Array [ + 45, + 48, + ], + "type": "TSLiteralType", + }, + "qualifier": Object { + "loc": Object { + "end": Object { + "column": 22, + "line": 2, + }, + "start": Object { + "column": 21, + "line": 2, + }, + }, + "name": "X", + "range": Array [ + 50, + 51, + ], + "type": "Identifier", + }, + "range": Array [ + 38, + 54, + ], + "type": "TSImportType", + "typeParameters": Object { + "loc": Object { + "end": Object { + "column": 25, + "line": 2, + }, + "start": Object { + "column": 22, + "line": 2, + }, + }, + "params": Array [ + Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 2, + }, + "start": Object { + "column": 23, + "line": 2, + }, + }, + "range": Array [ + 52, + 53, + ], + "type": "TSTypeReference", + "typeName": Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 2, + }, + "start": Object { + "column": 23, + "line": 2, + }, + }, + "name": "Y", + "range": Array [ + 52, + 53, + ], + "type": "Identifier", + }, + }, + ], + "range": Array [ + 51, + 54, + ], + "type": "TSTypeParameterInstantiation", + }, + }, + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 3, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 56, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 4, + ], + "type": "Identifier", + "value": "type", + }, + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 6, + ], + "type": "Identifier", + "value": "A", + }, + Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 8, + ], + "type": "Punctuator", + "value": "=", + }, + Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 1, + }, + "start": Object { + "column": 9, + "line": 1, + }, + }, + "range": Array [ + 9, + 15, + ], + "type": "Keyword", + "value": "typeof", + }, + Object { + "loc": Object { + "end": Object { + "column": 22, + "line": 1, + }, + "start": Object { + "column": 16, + "line": 1, + }, + }, + "range": Array [ + 16, + 22, + ], + "type": "Keyword", + "value": "import", + }, + Object { + "loc": Object { + "end": Object { + "column": 23, + "line": 1, + }, + "start": Object { + "column": 22, + "line": 1, + }, + }, + "range": Array [ + 22, + 23, + ], + "type": "Punctuator", + "value": "(", + }, + Object { + "loc": Object { + "end": Object { + "column": 26, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "range": Array [ + 23, + 26, + ], + "type": "String", + "value": "'A'", + }, + Object { + "loc": Object { + "end": Object { + "column": 27, + "line": 1, + }, + "start": Object { + "column": 26, + "line": 1, + }, + }, + "range": Array [ + 26, + 27, + ], + "type": "Punctuator", + "value": ")", + }, + Object { + "loc": Object { + "end": Object { + "column": 28, + "line": 1, + }, + "start": Object { + "column": 27, + "line": 1, + }, + }, + "range": Array [ + 27, + 28, + ], + "type": "Punctuator", + "value": ";", + }, + Object { + "loc": Object { + "end": Object { + "column": 4, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 2, + }, + }, + "range": Array [ + 29, + 33, + ], + "type": "Identifier", + "value": "type", + }, + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 2, + }, + "start": Object { + "column": 5, + "line": 2, + }, + }, + "range": Array [ + 34, + 35, + ], + "type": "Identifier", + "value": "B", + }, + Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 2, + }, + "start": Object { + "column": 7, + "line": 2, + }, + }, + "range": Array [ + 36, + 37, + ], + "type": "Punctuator", + "value": "=", + }, + Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 2, + }, + "start": Object { + "column": 9, + "line": 2, + }, + }, + "range": Array [ + 38, + 44, + ], + "type": "Keyword", + "value": "import", + }, + Object { + "loc": Object { + "end": Object { + "column": 16, + "line": 2, + }, + "start": Object { + "column": 15, + "line": 2, + }, + }, + "range": Array [ + 44, + 45, + ], + "type": "Punctuator", + "value": "(", + }, + Object { + "loc": Object { + "end": Object { + "column": 19, + "line": 2, + }, + "start": Object { + "column": 16, + "line": 2, + }, + }, + "range": Array [ + 45, + 48, + ], + "type": "String", + "value": "\\"B\\"", + }, + Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 2, + }, + "start": Object { + "column": 19, + "line": 2, + }, + }, + "range": Array [ + 48, + 49, + ], + "type": "Punctuator", + "value": ")", + }, + Object { + "loc": Object { + "end": Object { + "column": 21, + "line": 2, + }, + "start": Object { + "column": 20, + "line": 2, + }, + }, + "range": Array [ + 49, + 50, + ], + "type": "Punctuator", + "value": ".", + }, + Object { + "loc": Object { + "end": Object { + "column": 22, + "line": 2, + }, + "start": Object { + "column": 21, + "line": 2, + }, + }, + "range": Array [ + 50, + 51, + ], + "type": "Identifier", + "value": "X", + }, + Object { + "loc": Object { + "end": Object { + "column": 23, + "line": 2, + }, + "start": Object { + "column": 22, + "line": 2, + }, + }, + "range": Array [ + 51, + 52, + ], + "type": "Punctuator", + "value": "<", + }, + Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 2, + }, + "start": Object { + "column": 23, + "line": 2, + }, + }, + "range": Array [ + 52, + 53, + ], + "type": "Identifier", + "value": "Y", + }, + Object { + "loc": Object { + "end": Object { + "column": 25, + "line": 2, + }, + "start": Object { + "column": 24, + "line": 2, + }, + }, + "range": Array [ + 53, + 54, + ], + "type": "Punctuator", + "value": ">", + }, + Object { + "loc": Object { + "end": Object { + "column": 26, + "line": 2, + }, + "start": Object { + "column": 25, + "line": 2, + }, + }, + "range": Array [ + 54, + 55, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; + +exports[`typescript fixtures/basics/type-import-type-with-type-parameters-in-type-reference.src 1`] = ` +Object { + "body": Array [ + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "name": "X", + "range": Array [ + 5, + 6, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 30, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 30, + ], + "type": "TSTypeAliasDeclaration", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 29, + "line": 1, + }, + "start": Object { + "column": 9, + "line": 1, + }, + }, + "range": Array [ + 9, + 29, + ], + "type": "TSTypeReference", + "typeName": Object { + "loc": Object { + "end": Object { + "column": 10, + "line": 1, + }, + "start": Object { + "column": 9, + "line": 1, + }, + }, + "name": "A", + "range": Array [ + 9, + 10, + ], + "type": "Identifier", + }, + "typeParameters": Object { + "loc": Object { + "end": Object { + "column": 29, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "params": Array [ + Object { + "isTypeOf": false, + "loc": Object { + "end": Object { + "column": 28, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "parameter": Object { + "literal": Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 18, + "line": 1, + }, + }, + "range": Array [ + 18, + 20, + ], + "raw": "\\"\\"", + "type": "Literal", + "value": "", + }, + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 18, + "line": 1, + }, + }, + "range": Array [ + 18, + 20, + ], + "type": "TSLiteralType", + }, + "qualifier": Object { + "loc": Object { + "end": Object { + "column": 23, + "line": 1, + }, + "start": Object { + "column": 22, + "line": 1, + }, + }, + "name": "B", + "range": Array [ + 22, + 23, + ], + "type": "Identifier", + }, + "range": Array [ + 11, + 28, + ], + "type": "TSImportType", + "typeParameters": Object { + "loc": Object { + "end": Object { + "column": 28, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "params": Array [ + Object { + "loc": Object { + "end": Object { + "column": 27, + "line": 1, + }, + "start": Object { + "column": 24, + "line": 1, + }, + }, + "range": Array [ + 24, + 27, + ], + "type": "TSAnyKeyword", + }, + ], + "range": Array [ + 23, + 28, + ], + "type": "TSTypeParameterInstantiation", + }, + }, + ], + "range": Array [ + 10, + 29, + ], + "type": "TSTypeParameterInstantiation", + }, + }, + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 31, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 4, + ], + "type": "Identifier", + "value": "type", + }, + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 6, + ], + "type": "Identifier", + "value": "X", + }, + Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 8, + ], + "type": "Punctuator", + "value": "=", + }, + Object { + "loc": Object { + "end": Object { + "column": 10, + "line": 1, + }, + "start": Object { + "column": 9, + "line": 1, + }, + }, + "range": Array [ + 9, + 10, + ], + "type": "Identifier", + "value": "A", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "range": Array [ + 10, + 11, + ], + "type": "Punctuator", + "value": "<", + }, + Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "range": Array [ + 11, + 17, + ], + "type": "Keyword", + "value": "import", + }, + Object { + "loc": Object { + "end": Object { + "column": 18, + "line": 1, + }, + "start": Object { + "column": 17, + "line": 1, + }, + }, + "range": Array [ + 17, + 18, + ], + "type": "Punctuator", + "value": "(", + }, + Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 1, + }, + "start": Object { + "column": 18, + "line": 1, + }, + }, + "range": Array [ + 18, + 20, + ], + "type": "String", + "value": "\\"\\"", + }, + Object { + "loc": Object { + "end": Object { + "column": 21, + "line": 1, + }, + "start": Object { + "column": 20, + "line": 1, + }, + }, + "range": Array [ + 20, + 21, + ], + "type": "Punctuator", + "value": ")", + }, + Object { + "loc": Object { + "end": Object { + "column": 22, + "line": 1, + }, + "start": Object { + "column": 21, + "line": 1, + }, + }, + "range": Array [ + 21, + 22, + ], + "type": "Punctuator", + "value": ".", + }, + Object { + "loc": Object { + "end": Object { + "column": 23, + "line": 1, + }, + "start": Object { + "column": 22, + "line": 1, + }, + }, + "range": Array [ + 22, + 23, + ], + "type": "Identifier", + "value": "B", + }, + Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "range": Array [ + 23, + 24, + ], + "type": "Punctuator", + "value": "<", + }, + Object { + "loc": Object { + "end": Object { + "column": 27, + "line": 1, + }, + "start": Object { + "column": 24, + "line": 1, + }, + }, + "range": Array [ + 24, + 27, + ], + "type": "Identifier", + "value": "any", + }, + Object { + "loc": Object { + "end": Object { + "column": 28, + "line": 1, + }, + "start": Object { + "column": 27, + "line": 1, + }, + }, + "range": Array [ + 27, + 28, + ], + "type": "Punctuator", + "value": ">", + }, + Object { + "loc": Object { + "end": Object { + "column": 29, + "line": 1, + }, + "start": Object { + "column": 28, + "line": 1, + }, + }, + "range": Array [ + 28, + 29, + ], + "type": "Punctuator", + "value": ">", + }, + Object { + "loc": Object { + "end": Object { + "column": 30, + "line": 1, + }, + "start": Object { + "column": 29, + "line": 1, + }, + }, + "range": Array [ + 29, + 30, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; + exports[`typescript fixtures/basics/type-parameters-comments.src 1`] = ` Object { "body": Array [ @@ -134687,6 +137507,7 @@ Object { ], "type": "TSEnumDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 72, @@ -145776,6 +148597,7 @@ Object { "body": Object { "body": Array [ Object { + "importKind": "value", "loc": Object { "end": Object { "column": 22, @@ -146290,6 +149112,7 @@ Object { }, "type": "TSDeclareFunction", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 59, @@ -148070,6 +150893,7 @@ Object { ], "type": "VariableDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 32, @@ -148363,6 +151187,7 @@ Object { "superClass": null, "type": "ClassDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 5, @@ -148510,6 +151335,7 @@ Object { ], "type": "TSInterfaceDeclaration", }, + "exportKind": "type", "loc": Object { "end": Object { "column": 9, @@ -148579,6 +151405,7 @@ Object { ], "type": "TSModuleDeclaration", }, + "exportKind": "value", "loc": Object { "end": Object { "column": 5, diff --git a/yarn.lock b/yarn.lock index 05923ed503f9..20ca893a3921 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8152,10 +8152,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@*, "typescript@>=3.2.1 <3.8.0", typescript@^3.7.2: - version "3.7.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae" - integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw== +typescript@*, "typescript@>=3.2.1 <3.9.0", typescript@^3.8.3: + version "3.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" + integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== uglify-js@^3.1.4: version "3.6.0"