-
-
Notifications
You must be signed in to change notification settings - Fork 58
Open
Description
Before You File a Bug Report Please Confirm You Have Done The Following...
- I have tried restarting my IDE and the issue persists.
- I have updated to the latest version of the packages.
What version of ESLint are you using?
9.36.0
What version of eslint-plugin-svelte
are you using?
3.12.4
What did you do?
Configuration from README:
Configuration
import js from "@eslint/js";
import svelte from "eslint-plugin-svelte";
import globals from "globals";
import ts from "typescript-eslint";
import svelteConfig from "./svelte.config.js";
export default ts.config(
js.configs.recommended,
...ts.configs.recommended,
...svelte.configs.recommended,
{
languageOptions: {
globals: {
...globals.browser,
...globals.node,
},
},
},
{
files: ["**/*.svelte", "**/*.svelte.ts", "**/*.svelte.js"],
// See more details at: https://typescript-eslint.io/packages/parser/
languageOptions: {
parserOptions: {
projectService: true,
extraFileExtensions: [".svelte"], // Add support for additional file extensions, such as .svelte
parser: ts.parser,
// Specify a parser for each language, if needed:
// parser: {
// ts: ts.parser,
// js: espree, // Use espree for .js files (add: import espree from 'espree')
// typescript: ts.parser
// },
// We recommend importing and specifying svelte.config.js.
// By doing so, some rules in eslint-plugin-svelte will automatically read the configuration and adjust their behavior accordingly.
// While certain Svelte settings may be statically loaded from svelte.config.js even if you don’t specify it,
// explicitly specifying it ensures better compatibility and functionality.
//
// If non-serializable properties are included, running ESLint with the --cache flag will fail.
// In that case, please remove the non-serializable properties. (e.g. `svelteConfig: { ...svelteConfig, kit: { ...svelteConfig.kit, typescript: undefined }}`)
svelteConfig,
},
},
},
{
rules: {
// Override or add rule settings here, such as:
// 'svelte/rule-name': 'error'
},
}
);
Below svelte code copied verbatim from shadcn-svelte data table component.
import {
type RowData,
type TableOptions,
type TableOptionsResolved,
type TableState,
createTable,
} from "@tanstack/table-core";
/**
* Creates a reactive TanStack table object for Svelte.
* @param options Table options to create the table with.
* @returns A reactive table object.
* @example
* ```svelte
* <script>
* const table = createSvelteTable({ ... })
* </script>
*
* <table>
* <thead>
* {#each table.getHeaderGroups() as headerGroup}
* <tr>
* {#each headerGroup.headers as header}
* <th colspan={header.colSpan}>
* <FlexRender content={header.column.columnDef.header} context={header.getContext()} />
* </th>
* {/each}
* </tr>
* {/each}
* </thead>
* <!-- ... -->
* </table>
* ```
*/
export function createSvelteTable<TData extends RowData>(options: TableOptions<TData>) {
const resolvedOptions: TableOptionsResolved<TData> = mergeObjects(
{
state: {},
onStateChange() {},
renderFallbackValue: null,
mergeOptions: (
defaultOptions: TableOptions<TData>,
options: Partial<TableOptions<TData>>
) => {
return mergeObjects(defaultOptions, options);
},
},
options
);
const table = createTable(resolvedOptions);
let state = $state<Partial<TableState>>(table.initialState);
function updateOptions() {
table.setOptions((prev) => {
return mergeObjects(prev, options, {
state: mergeObjects(state, options.state || {}),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onStateChange: (updater: any) => {
if (updater instanceof Function) state = updater(state);
else state = mergeObjects(state, updater);
options.onStateChange?.(updater);
},
});
});
}
updateOptions();
$effect.pre(() => {
updateOptions();
});
return table;
}
type MaybeThunk<T extends object> = T | (() => T | null | undefined);
type Intersection<T extends readonly unknown[]> = (T extends [infer H, ...infer R]
? H & Intersection<R>
: unknown) & {};
/**
* Lazily merges several objects (or thunks) while preserving
* getter semantics from every source.
*
* Proxy-based to avoid known WebKit recursion issue.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function mergeObjects<Sources extends readonly MaybeThunk<any>[]>(
...sources: Sources
): Intersection<{ [K in keyof Sources]: Sources[K] }> {
const resolve = <T extends object>(src: MaybeThunk<T>): T | undefined =>
typeof src === "function" ? (src() ?? undefined) : src;
const findSourceWithKey = (key: PropertyKey) => {
for (let i = sources.length - 1; i >= 0; i--) {
const obj = resolve(sources[i]);
if (obj && key in obj) return obj;
}
return undefined;
};
return new Proxy(Object.create(null), {
get(_, key) {
const src = findSourceWithKey(key);
return src?.[key as never];
},
has(_, key) {
return !!findSourceWithKey(key);
},
ownKeys(): (string | symbol)[] {
const all = new Set<string | symbol>();
for (const s of sources) {
const obj = resolve(s);
if (obj) {
for (const k of Reflect.ownKeys(obj) as (string | symbol)[]) {
all.add(k);
}
}
}
return [...all];
},
getOwnPropertyDescriptor(_, key) {
const src = findSourceWithKey(key);
if (!src) return undefined;
return {
configurable: true,
enumerable: true,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value: (src as any)[key],
writable: true,
};
},
}) as Intersection<{ [K in keyof Sources]: Sources[K] }>;
}
What did you expect to happen?
svelte rules should trigger once only for svelte.ts files
What actually happened?
svelte rules trigger twice:
% npm run lint
> [email protected] lint
> prettier --check . && eslint .
Checking formatting...
All matched files use Prettier code style!
...
/.../src/lib/components/ui/data-table/data-table.svelte.ts
117:25 error Found a mutable instance of the built-in Set class. Use SvelteSet instead svelte/prefer-svelte-reactivity
117:25 error Found a mutable instance of the built-in Set class. Use SvelteSet instead svelte/prefer-svelte-reactivity
✖ 19 problems (19 errors, 0 warnings)
This is on a fresh install where we installed shadcn-svelte to verify
Link to GitHub Repo with Minimal Reproducible Example
eslint online playground does not seem to work. Repro steps:
- initialize a svelte project
- add the above file
- run
npm run lint
- see duplicate eslint errors
Additional comments
No response
Metadata
Metadata
Assignees
Labels
No labels