Skip to content

Commit cc7dbbd

Browse files
authored
fix: wrong store access type information (#204)
* fix: wrong store access type information * Create grumpy-avocados-behave.md * test: update new fixture * test: ignore ts-eslint v4
1 parent 9c39528 commit cc7dbbd

11 files changed

+16143
-9
lines changed

.changeset/grumpy-avocados-behave.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte-eslint-parser": patch
3+
---
4+
5+
fix: wrong store access type information

src/context/script-let.ts

+25-4
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ export class ScriptLetContext {
116116

117117
private readonly usedUniqueIds = new Set<string>();
118118

119+
private storeValueTypeName: string | undefined;
120+
119121
public constructor(ctx: Context) {
120122
this.script = ctx.sourceCode.scripts;
121123
this.ctx = ctx;
@@ -537,8 +539,27 @@ export class ScriptLetContext {
537539
for (const nm of maybeStores) {
538540
if (reservedNames.has(nm)) continue;
539541

542+
if (!this.storeValueTypeName) {
543+
this.storeValueTypeName = this.generateUniqueId("StoreValueType");
544+
545+
this.appendScriptWithoutOffset(
546+
`type ${this.storeValueTypeName}<T> = T extends null | undefined
547+
? T
548+
: T extends object & { subscribe(run: infer F, ...args: any): any }
549+
? F extends (value: infer V, ...args: any) => any
550+
? V
551+
: never
552+
: T;`,
553+
(node, tokens, comments, result) => {
554+
tokens.length = 0;
555+
comments.length = 0;
556+
removeAllScope(node, result);
557+
}
558+
);
559+
}
560+
540561
this.appendScriptWithoutOffset(
541-
`declare let $${nm}: Parameters<Parameters<(typeof ${nm})["subscribe"]>[0]>[0];`,
562+
`declare let $${nm}: ${this.storeValueTypeName}<typeof ${nm}>;`,
542563
(node, tokens, comments, result) => {
543564
tokens.length = 0;
544565
comments.length = 0;
@@ -933,9 +954,9 @@ function removeAllScope(target: ESTree.Node, result: ScriptLetCallbackOption) {
933954
}
934955
if (node.type === "Identifier") {
935956
let scope = result.getInnermostScope(node);
936-
if (
937-
(scope.block as any).type === "TSTypeAliasDeclaration" &&
938-
(scope.block as any).id === node
957+
while (
958+
target.range![0] <= scope.block.range![0] &&
959+
scope.block.range![1] <= target.range![1]
939960
) {
940961
scope = scope.upper!;
941962
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts">
2-
import { writable } from 'svelte/store'; // writable: <T>(value?: T, start?: StartStopNotifier<T>) => Writable<T>, writable: <T>(value?: T, start?: StartStopNotifier<T>) => Writable<T>
2+
import { writable } from 'svelte/store'; // writable: <T>(value?: T | undefined, start?: StartStopNotifier<T> | undefined) => Writable<T>, writable: <T>(value?: T | undefined, start?: StartStopNotifier<T> | undefined) => Writable<T>
33
const a = writable(0) // a: Writable<number>, writable(0): Writable<number>
44
const b = writable(0) // b: Writable<number>, writable(0): Writable<number>
55
const $b = 'abc' // $b: "abc"
@@ -10,5 +10,5 @@
1010
{b} <!-- b: Writable<number> -->
1111
{$b} <!-- $b: "abc" -->
1212
{c} <!-- c: "abc" -->
13-
{$c} <!-- $c: never -->
14-
{$d} <!-- $d: never -->
13+
{$c} <!-- $c: "abc" -->
14+
{$d} <!-- $d: any -->

tests/fixtures/parser/ast/ts-store02-type-output.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script context="module" lang="ts">
2-
import { writable } from 'svelte/store'; // writable: <T>(value?: T, start?: StartStopNotifier<T>) => Writable<T>, writable: <T>(value?: T, start?: StartStopNotifier<T>) => Writable<T>
2+
import { writable } from 'svelte/store'; // writable: <T>(value?: T | undefined, start?: StartStopNotifier<T> | undefined) => Writable<T>, writable: <T>(value?: T | undefined, start?: StartStopNotifier<T> | undefined) => Writable<T>
33
const a = writable(0) // a: Writable<number>, writable(0): Writable<number>
44
declare const $a: string // $a: string
55
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script lang="ts">
2+
import { Writable, Readable } from 'svelte/store';
3+
let maybeUndef: Writable<number> | undefined
4+
let maybeNull: Readable<string> | null
5+
let maybeNullAndStr: Readable<boolean> | null | string
6+
7+
export function fn() {
8+
$maybeUndef;
9+
$maybeNull;
10+
$maybeNullAndStr;
11+
}
12+
</script>
13+
{$maybeUndef}
14+
{$maybeNull}
15+
{$maybeNullAndStr}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[
2+
{
3+
"ruleId": "no-unused-expressions",
4+
"code": "$maybeUndef;",
5+
"line": 8,
6+
"column": 3
7+
},
8+
{
9+
"ruleId": "no-unused-expressions",
10+
"code": "$maybeNull;",
11+
"line": 9,
12+
"column": 3
13+
},
14+
{
15+
"ruleId": "no-unused-expressions",
16+
"code": "$maybeNullAndStr;",
17+
"line": 10,
18+
"column": 3
19+
}
20+
]

0 commit comments

Comments
 (0)