diff --git a/.changeset/strange-eagles-judge.md b/.changeset/strange-eagles-judge.md new file mode 100644 index 000000000..0af27cf5a --- /dev/null +++ b/.changeset/strange-eagles-judge.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-svelte": patch +--- + +fix(no-unused-props): false positives for `ComponentProps` diff --git a/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts b/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts index 0ccefcebf..718032c60 100644 --- a/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts +++ b/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts @@ -1,5 +1,5 @@ import { createRule } from '../utils/index.js'; -import { getTypeScriptTools } from '../utils/ts-utils/index.js'; +import { getTypeScriptTools, isAnyType } from '../utils/ts-utils/index.js'; import type { TSESTree } from '@typescript-eslint/types'; import type ts from 'typescript'; import { findVariable } from '../utils/ast-utils.js'; @@ -341,7 +341,9 @@ export default createRule('no-unused-props', { if (parentPath.length === 0) { const indexType = propsType.getStringIndexType(); const numberIndexType = propsType.getNumberIndexType(); - const hasIndexSignature = Boolean(indexType) || Boolean(numberIndexType); + const hasIndexSignature = + Boolean(indexType && !isAnyType(indexType, tools!.ts)) || + Boolean(numberIndexType && !isAnyType(numberIndexType, tools!.ts)); if (hasIndexSignature && !hasRestElement(declaredPropertyNames)) { context.report({ diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/component-props-any-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/component-props-any-input.svelte new file mode 100644 index 000000000..7e43876a0 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/component-props-any-input.svelte @@ -0,0 +1,11 @@ + + +

{a}

diff --git a/packages/eslint-plugin-svelte/tests/utils/utils.ts b/packages/eslint-plugin-svelte/tests/utils/utils.ts index d882cc2ed..0b503dd88 100644 --- a/packages/eslint-plugin-svelte/tests/utils/utils.ts +++ b/packages/eslint-plugin-svelte/tests/utils/utils.ts @@ -69,11 +69,13 @@ export function getRuleFixturesRoot(ruleName: string): string { } function fileNameSuffix(fileName: string): string { - return fileName.match(/\.svelte\.(?:j|t)s$/u) ? fileName.slice(fileName.length - 10) : path.extname(fileName); + return fileName.match(/\.svelte\.(?:j|t)s$/u) + ? fileName.slice(fileName.length - 10) + : path.extname(fileName); } -function isSvelteFile(fileName): boolean { - return fileName.match(/\.svelte(?:\.(?:j|t)s)?$/u); +function isSvelteFile(fileName: string): boolean { + return Boolean(fileName.match(/\.svelte(?:\.(?:j|t)s)?$/u)); } /** @@ -230,13 +232,12 @@ function writeFixtures( const config = getConfig(ruleName, inputFile); - const parser = - isSvelteFile(inputFile) - ? svelteParser - : path.extname(inputFile) === '.ts' - ? typescriptParser - : undefined; - const { code, filename, options, ...verifyConfig } = config; + const parser = isSvelteFile(inputFile) + ? svelteParser + : path.extname(inputFile) === '.ts' + ? typescriptParser + : undefined; + const { code, filename, options, only, ...verifyConfig } = config; const resolvedParser = verifyConfig.languageOptions?.parser ?? parser; const result = linter.verify( code, @@ -251,7 +252,7 @@ function writeFixtures( }, languageOptions: { globals: globals.browser, - ecmaVersion:"latest", + ecmaVersion: 'latest', sourceType: 'module', ...verifyConfig?.languageOptions, parserOptions: { @@ -320,12 +321,11 @@ function getConfig(ruleName: string, inputFile: string) { ? require(configFile) : JSON.parse(fs.readFileSync(configFile, 'utf8')); } - const parser = - isSvelteFile(filename) - ? svelteParser - : path.extname(inputFile) === '.ts' - ? typescriptParser - : undefined; + const parser = isSvelteFile(filename) + ? svelteParser + : path.extname(inputFile) === '.ts' + ? typescriptParser + : undefined; const resolvedParser = config?.languageOptions?.parser ? require(config.languageOptions.parser) @@ -335,7 +335,7 @@ function getConfig(ruleName: string, inputFile: string) { ...config, languageOptions: { globals: globals.browser, - ecmaVersion:"latest", + ecmaVersion: 'latest', sourceType: 'module', ...config?.languageOptions, parserOptions: { @@ -359,7 +359,10 @@ function getConfig(ruleName: string, inputFile: string) { } function getRequirements(inputFile: string): Record { - let requirementsFile: string = inputFile.replace(/(input|\+.+)(?:\.[a-z]+)+$/u, 'requirements.json'); + let requirementsFile: string = inputFile.replace( + /(input|\+.+)(?:\.[a-z]+)+$/u, + 'requirements.json' + ); if (!fs.existsSync(requirementsFile)) { requirementsFile = path.join(path.dirname(inputFile), '_requirements.json'); }