diff --git a/.changeset/twenty-pandas-tie.md b/.changeset/twenty-pandas-tie.md new file mode 100644 index 00000000..1a6b1ec9 --- /dev/null +++ b/.changeset/twenty-pandas-tie.md @@ -0,0 +1,5 @@ +--- +"svelte-eslint-parser": patch +--- + +fix: wrong type information for `#await` with same id diff --git a/src/parser/converts/block.ts b/src/parser/converts/block.ts index 2bdd85a8..14daf9c9 100644 --- a/src/parser/converts/block.ts +++ b/src/parser/converts/block.ts @@ -307,7 +307,11 @@ export function convertAwaitBlock( }; } const idAwaitThenValue = typeCtx.generateUniqueId("AwaitThenValue"); - if (node.expression.type === "Identifier") { + if ( + node.expression.type === "Identifier" && + // We cannot use type annotations like `(x: Foo)` if they have the same identifier name. + !hasIdentifierFor(node.expression.name, baseParam.node) + ) { return { preparationScript: [generateAwaitThenValueType(idAwaitThenValue)], param: { @@ -484,3 +488,30 @@ function generateAwaitThenValueType(id: string) { : never : T;`; } + +/** Checks whether the given name identifier is exists or not. */ +function hasIdentifierFor(name: string, node: ESTree.Pattern): boolean { + if (node.type === "Identifier") { + return node.name === name; + } + if (node.type === "ObjectPattern") { + return node.properties.some((property) => + property.type === "Property" + ? hasIdentifierFor(name, property.value) + : hasIdentifierFor(name, property) + ); + } + if (node.type === "ArrayPattern") { + return node.elements.some( + (element) => element && hasIdentifierFor(name, element) + ); + } + if (node.type === "RestElement") { + return hasIdentifierFor(name, node.argument); + } + if (node.type === "AssignmentPattern") { + return hasIdentifierFor(name, node.left); + } + + return false; +} diff --git a/tests/fixtures/integrations/type-info-tests/await-with-same-id-input.svelte b/tests/fixtures/integrations/type-info-tests/await-with-same-id-input.svelte new file mode 100644 index 00000000..713b60b9 --- /dev/null +++ b/tests/fixtures/integrations/type-info-tests/await-with-same-id-input.svelte @@ -0,0 +1,37 @@ + + +{#await a} +
await
+{:then a} +
{a.x}
+{/await} + +{#await b} +
await
+{:then { x: b = 42 }} +
{b.toExponential()}
+{/await} + +{#await c} +
await
+{:then {...c}} +
{c.x}
+{/await} + +{#await d} +
await
+{:then [d]} +
{d.toExponential()}
+{/await} + +{#await e} +
await
+{:then [...e]} +
{e[0].toExponential()}
+{/await} diff --git a/tests/fixtures/integrations/type-info-tests/await-with-same-id-output.json b/tests/fixtures/integrations/type-info-tests/await-with-same-id-output.json new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/tests/fixtures/integrations/type-info-tests/await-with-same-id-output.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/tests/fixtures/integrations/type-info-tests/await-with-same-id-setup.ts b/tests/fixtures/integrations/type-info-tests/await-with-same-id-setup.ts new file mode 100644 index 00000000..de06e86a --- /dev/null +++ b/tests/fixtures/integrations/type-info-tests/await-with-same-id-setup.ts @@ -0,0 +1,24 @@ +/* eslint eslint-comments/require-description: 0, @typescript-eslint/explicit-module-boundary-types: 0 */ +import type { Linter } from "eslint"; +import { generateParserOptions } from "../../../src/parser/test-utils"; +import { rules } from "@typescript-eslint/eslint-plugin"; +export function setupLinter(linter: Linter) { + linter.defineRule( + "@typescript-eslint/no-unsafe-member-access", + rules["no-unsafe-member-access"] as never + ); +} + +export function getConfig() { + return { + parser: "svelte-eslint-parser", + parserOptions: generateParserOptions(), + rules: { + "@typescript-eslint/no-unsafe-member-access": "error", + }, + env: { + browser: true, + es2021: true, + }, + }; +} diff --git a/tests/fixtures/parser/ast/ts-store01-input.svelte b/tests/fixtures/parser/ast/ts-store01-input.svelte index b9c18335..d43735f9 100644 --- a/tests/fixtures/parser/ast/ts-store01-input.svelte +++ b/tests/fixtures/parser/ast/ts-store01-input.svelte @@ -11,4 +11,4 @@ {$b} {c} {$c} -{$d} +{$unknown} diff --git a/tests/fixtures/parser/ast/ts-store01-no-undef-result.json b/tests/fixtures/parser/ast/ts-store01-no-undef-result.json index de5e1a7b..6f669557 100644 --- a/tests/fixtures/parser/ast/ts-store01-no-undef-result.json +++ b/tests/fixtures/parser/ast/ts-store01-no-undef-result.json @@ -1,7 +1,7 @@ [ { "ruleId": "no-undef", - "code": "$d", + "code": "$unknown", "line": 14, "column": 2 } diff --git a/tests/fixtures/parser/ast/ts-store01-output.json b/tests/fixtures/parser/ast/ts-store01-output.json index e364cc03..325c8e68 100644 --- a/tests/fixtures/parser/ast/ts-store01-output.json +++ b/tests/fixtures/parser/ast/ts-store01-output.json @@ -1012,10 +1012,10 @@ "kind": "text", "expression": { "type": "Identifier", - "name": "$d", + "name": "$unknown", "range": [ 197, - 199 + 205 ], "loc": { "start": { @@ -1024,13 +1024,13 @@ }, "end": { "line": 14, - "column": 3 + "column": 9 } } }, "range": [ 196, - 200 + 206 ], "loc": { "start": { @@ -1039,7 +1039,7 @@ }, "end": { "line": 14, - "column": 4 + "column": 10 } } } @@ -2291,10 +2291,10 @@ }, { "type": "Identifier", - "value": "$d", + "value": "$unknown", "range": [ 197, - 199 + 205 ], "loc": { "start": { @@ -2303,7 +2303,7 @@ }, "end": { "line": 14, - "column": 3 + "column": 9 } } }, @@ -2311,24 +2311,24 @@ "type": "Punctuator", "value": "}", "range": [ - 199, - 200 + 205, + 206 ], "loc": { "start": { "line": 14, - "column": 3 + "column": 9 }, "end": { "line": 14, - "column": 4 + "column": 10 } } } ], "range": [ 0, - 201 + 207 ], "loc": { "start": { diff --git a/tests/fixtures/parser/ast/ts-store01-scope-output.json b/tests/fixtures/parser/ast/ts-store01-scope-output.json index ff9129c7..ed305b45 100644 --- a/tests/fixtures/parser/ast/ts-store01-scope-output.json +++ b/tests/fixtures/parser/ast/ts-store01-scope-output.json @@ -10847,10 +10847,10 @@ { "identifier": { "type": "Identifier", - "name": "$d", + "name": "$unknown", "range": [ 197, - 199 + 205 ], "loc": { "start": { @@ -10859,7 +10859,7 @@ }, "end": { "line": 14, - "column": 3 + "column": 9 } } }, @@ -10873,10 +10873,10 @@ { "identifier": { "type": "Identifier", - "name": "$d", + "name": "$unknown", "range": [ 197, - 199 + 205 ], "loc": { "start": { @@ -10885,7 +10885,7 @@ }, "end": { "line": 14, - "column": 3 + "column": 9 } } }, @@ -10900,10 +10900,10 @@ { "identifier": { "type": "Identifier", - "name": "$d", + "name": "$unknown", "range": [ 197, - 199 + 205 ], "loc": { "start": { @@ -10912,7 +10912,7 @@ }, "end": { "line": 14, - "column": 3 + "column": 9 } } }, diff --git a/tests/fixtures/parser/ast/ts-store01-type-output.svelte b/tests/fixtures/parser/ast/ts-store01-type-output.svelte index e9a31e9b..9d50305a 100644 --- a/tests/fixtures/parser/ast/ts-store01-type-output.svelte +++ b/tests/fixtures/parser/ast/ts-store01-type-output.svelte @@ -11,4 +11,4 @@ {$b} {c} {$c} -{$d} +{$unknown}