Skip to content

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

Open
@jdesrosiers

Description

@jdesrosiers

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions