Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESLint doesn't know types of functions on components #1150

Open
2 tasks done
jdesrosiers opened this issue Mar 22, 2025 · 2 comments
Open
2 tasks done

ESLint doesn't know types of functions on components #1150

jdesrosiers opened this issue Mar 22, 2025 · 2 comments

Comments

@jdesrosiers
Copy link

jdesrosiers commented Mar 22, 2025

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.23.0

What version of eslint-plugin-svelte are you using?

3.3.3

What did you do?

Configuration
import svelte from 'eslint-plugin-svelte';
import ts from 'typescript-eslint';
import svelteConfig from './svelte.config.js';

export default ts.config(
  { ignores: [".svelte-kit", "eslint.config.js", "svelte.config.js"] },
  ...ts.configs.recommendedTypeChecked,
  {
    languageOptions: {
      parserOptions: {
        projectService: true
      }
    }
  },
  ...svelte.configs.recommended,
  {
    files: ["**/*.svelte", "**/*.svelte.ts", "**/*.svelte.js"],
    languageOptions: {
      parserOptions: {
        extraFileExtensions: ['.svelte'],
        parser: ts.parser,
        svelteConfig
      }
    }
  },
);

routes/+page.svelte

<script lang="ts">
  import Foo from "../components/Foo.svelte";

  let foo: Foo | undefined = $state();

  const focus = () => {
    foo!.focus();
  }
</script>

<button onclick={() => focus()}>Focus</button>
<Foo bind:this={foo} />

components/Foo.svelte

<script lang="ts">
  let src: HTMLTextAreaElement | undefined = $state();

  export const focus = () => {
    src!.focus();
  };
</script>

<textarea bind:this={src}></textarea>

What did you expect to happen?

ESLint should produce no errors.

What actually happened?

/*redacted*/src/routes/+page.svelte
  7:5  error  Unsafe call of a(n) `any` typed value  @typescript-eslint/no-unsafe-call

✖ 1 problem (1 error, 0 warnings)

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/jdesrosiers/svelte-eslint-component-function-bug-demo

Additional comments

The language server seems to understand the type correctly, but ESLint thinks it's any.

It reports this on foo,

let foo: ({
    $on?(type: string, callback: (e: any) => void): () => void;
    $set?(props: Partial<Record<string, never>>): void;
} & {
    focus: () => void;
}) | undefined

and this on focus,

(property) focus: () => void
@baseballyama
Copy link
Member

To get better types, consider using the following library. We’ll add detailed usage instructions to the README in the future.

https://github.com/ota-meshi/typescript-eslint-parser-for-extra-files

@jdesrosiers
Copy link
Author

Thanks for the tip. When I use that plugin, the error changes from,

Unsafe call of a(n) any typed value

to

Unsafe call of a(n) error type typed value

I have no idea how to debug what eslint thinks is wrong with the type.

I've updated the demo repo to include the plugin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants