Skip to content

Commit

Permalink
fix: wrong store access type information (#204)
Browse files Browse the repository at this point in the history
* fix: wrong store access type information

* Create grumpy-avocados-behave.md

* test: update new fixture

* test: ignore ts-eslint v4
  • Loading branch information
ota-meshi authored Aug 30, 2022
1 parent 9c39528 commit cc7dbbd
Show file tree
Hide file tree
Showing 11 changed files with 16,143 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/grumpy-avocados-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"svelte-eslint-parser": patch
---

fix: wrong store access type information
29 changes: 25 additions & 4 deletions src/context/script-let.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ export class ScriptLetContext {

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

private storeValueTypeName: string | undefined;

public constructor(ctx: Context) {
this.script = ctx.sourceCode.scripts;
this.ctx = ctx;
Expand Down Expand Up @@ -537,8 +539,27 @@ export class ScriptLetContext {
for (const nm of maybeStores) {
if (reservedNames.has(nm)) continue;

if (!this.storeValueTypeName) {
this.storeValueTypeName = this.generateUniqueId("StoreValueType");

this.appendScriptWithoutOffset(
`type ${this.storeValueTypeName}<T> = T extends null | undefined
? T
: T extends object & { subscribe(run: infer F, ...args: any): any }
? F extends (value: infer V, ...args: any) => any
? V
: never
: T;`,
(node, tokens, comments, result) => {
tokens.length = 0;
comments.length = 0;
removeAllScope(node, result);
}
);
}

this.appendScriptWithoutOffset(
`declare let $${nm}: Parameters<Parameters<(typeof ${nm})["subscribe"]>[0]>[0];`,
`declare let $${nm}: ${this.storeValueTypeName}<typeof ${nm}>;`,
(node, tokens, comments, result) => {
tokens.length = 0;
comments.length = 0;
Expand Down Expand Up @@ -933,9 +954,9 @@ function removeAllScope(target: ESTree.Node, result: ScriptLetCallbackOption) {
}
if (node.type === "Identifier") {
let scope = result.getInnermostScope(node);
if (
(scope.block as any).type === "TSTypeAliasDeclaration" &&
(scope.block as any).id === node
while (
target.range![0] <= scope.block.range![0] &&
scope.block.range![1] <= target.range![1]
) {
scope = scope.upper!;
}
Expand Down
6 changes: 3 additions & 3 deletions tests/fixtures/parser/ast/ts-store01-type-output.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { writable } from 'svelte/store'; // writable: <T>(value?: T, start?: StartStopNotifier<T>) => Writable<T>, writable: <T>(value?: T, start?: StartStopNotifier<T>) => Writable<T>
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>
const a = writable(0) // a: Writable<number>, writable(0): Writable<number>
const b = writable(0) // b: Writable<number>, writable(0): Writable<number>
const $b = 'abc' // $b: "abc"
Expand All @@ -10,5 +10,5 @@
{b} <!-- b: Writable<number> -->
{$b} <!-- $b: "abc" -->
{c} <!-- c: "abc" -->
{$c} <!-- $c: never -->
{$d} <!-- $d: never -->
{$c} <!-- $c: "abc" -->
{$d} <!-- $d: any -->
2 changes: 1 addition & 1 deletion tests/fixtures/parser/ast/ts-store02-type-output.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script context="module" lang="ts">
import { writable } from 'svelte/store'; // writable: <T>(value?: T, start?: StartStopNotifier<T>) => Writable<T>, writable: <T>(value?: T, start?: StartStopNotifier<T>) => Writable<T>
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>
const a = writable(0) // a: Writable<number>, writable(0): Writable<number>
declare const $a: string // $a: string
</script>
Expand Down
15 changes: 15 additions & 0 deletions tests/fixtures/parser/ast/ts-store03-input.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import { Writable, Readable } from 'svelte/store';
let maybeUndef: Writable<number> | undefined
let maybeNull: Readable<string> | null
let maybeNullAndStr: Readable<boolean> | null | string
export function fn() {
$maybeUndef;
$maybeNull;
$maybeNullAndStr;
}
</script>
{$maybeUndef}
{$maybeNull}
{$maybeNullAndStr}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[
{
"ruleId": "no-unused-expressions",
"code": "$maybeUndef;",
"line": 8,
"column": 3
},
{
"ruleId": "no-unused-expressions",
"code": "$maybeNull;",
"line": 9,
"column": 3
},
{
"ruleId": "no-unused-expressions",
"code": "$maybeNullAndStr;",
"line": 10,
"column": 3
}
]
Loading

0 comments on commit cc7dbbd

Please sign in to comment.