Skip to content
\n

What did you expect to happen?
\nVue instance methods and computed properties to be understood as already bound.

\n

What actually happened?

\n\n

Hitting this for all uses of computed properties and methods, which are all automatically bound by Vue already. eslint-config-typescript and vue-eslint-parser. Also, vue-tsc misunderstands computed properties as () -> ActualType instead of ActualType resulting in errors like Argument of type '() => ActualType' is not assignable to parameter of type 'ActualType'

\n
error  Avoid referencing unbound methods which may cause unintentional scoping of `this`. \nIf your function does not access `this`, you can annotate it with `this: void`, or consider using an arrow function instead  @typescript-eslint/unbound-method\n
\n

eslint.config.js:

\n
import {\n  defineConfigWithVueTs,\n  vueTsConfigs,\n} from \"@vue/eslint-config-typescript\";\nimport { globalIgnores } from \"eslint/config\";\nimport prettierConfig from \"@vue/eslint-config-prettier\";\nimport standard from \"@vue/eslint-config-standard-with-typescript\";\nimport globals from \"globals\";\nimport tsParser from \"@typescript-eslint/parser\";\nimport vueParser from \"vue-eslint-parser\";\nimport js from \"@eslint/js\";\nimport pluginVue from \"eslint-plugin-vue\";\nimport storybook from \"eslint-plugin-storybook\";\n\nexport default defineConfigWithVueTs(\n  globalIgnores([\n    \"node_modules\",\n    \"dist/\",\n    \"components/*/dist/\",\n    \"**/index.d.ts\",\n  ]),\n  js.configs.recommended,\n  standard,\n  storybook.configs[\"flat/recommended\"],\n  vueTsConfigs.recommendedTypeChecked,\n  pluginVue.configs[\"flat/recommended\"],\n  prettierConfig,\n  {\n    name: \"our-project/base\",\n    files: [\"**/*.{js,jsx,ts,tsx,vue}\"],\n    languageOptions: {\n      globals: {\n        ...globals.node,\n        ...globals.browser,\n      },\n      sourceType: \"module\",\n      ecmaVersion: \"latest\",\n      parser: vueParser,\n      parserOptions: {\n        parser: tsParser,\n        projectService: true,\n        sourceType: \"module\",\n        tsconfigRootDir: import.meta.dirname,\n      },\n    },\n    rules: {\n      []\n    }\n  }\n);
\n

tsconfig.json:

\n
{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"strict\": true,\n    \"jsx\": \"preserve\",\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"skipLibCheck\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"sourceMap\": true,\n    \"resolveJsonModule\": true,\n    \"verbatimModuleSyntax\": true,\n    \"types\": [\"node\", \"vue\", \"vitest/globals\"],\n    \"allowJs\": true,\n    \"checkJs\": true,\n  },\n  \"include\": [\n    \"**/*.ts\",\n    \"**/*.tsx\",\n    \"**/*.vue\",\n    \"**/*.js\",\n  ],\n  \"extends\": [\n    \"@vue/tsconfig/tsconfig.dom.json\",\n    \"@vue/tsconfig/tsconfig.lib.json\"\n  ],\n  \"exclude\": [\"node_modules\", \"types\", \"dist\"]\n}
","upvoteCount":1,"answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"

Sorry, haven't had time to figure out the minimum reproduction (our project is quite large), but I managed to find a couple of fixes/workarounds, one of which was intended for Vue 2 even though we are on the latest Vue 3 and vue-tsc. It's unclear which one(s) are the \"actual\" cause(s), but these helped:

\n

Manually type mapState, mapGetters, etc.

\n

For computed variables / component properties & methods issue, this worked well for some cases (for example in a component library where the final type for your Vuex or Pinia store can't be specified yet: https://stackoverflow.com/a/70983629/2836299

\n

Use of deprecated computed cache invalidation

\n

Trying to invalidate cache for computed variables as described in the guide has been deprecated as of Vue2. It seems that this:

\n
template: '<p>message: {{ timeMessage }}</p>',\ncomputed: {\n  timeMessage: {\n    cache: false,\n    get: function () {\n      return Date.now() + this.message\n    }\n  }\n}
\n

results in the inferred type for the computed property being invalid, not only because of the no-longer-supported cache property, but also because explicitly defining get() implies that set() will also be provided.

\n

Ensure circular dependencies are explicitly type annotated

\n
import type MyDependentComponent from \"./MyDependentComponent\";\nimport { defineAsyncComponent, defineComponent } from \"vue\";\n\nexport default defineComponent({\n  name: \"MyComponent\",\n  components: {\n    MyDependentComponent: defineAsyncComponent<typeof MyDependentComponent>( // <-- Important bit\n      () => import(\"MyDependentComponent\")\n    ),\n  },
\n

Add an empty script setup tag

\n

This worked for at least one component, but did break again and required the solutions above. While it reduced noise in my IDE, once other issues were fixed, this resulted in error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.ts-plugin(7056)

\n

@iraklisg opened on Jul 8, 2022:

\n
\n

As a workaround, using a normal <script> alongside <script setup> that defines a name property makes the error dissappear

\n
<script setup lang=\"ts\">\n// SEE: https://github.com/vuejs/vue/issues/12637\n</script>\n\n<script lang=\"ts\">\nexport default {\n  name: 'HelloWorld.'\n}\n</script>
\n
","upvoteCount":0,"url":"https://github.com/vuejs/language-tools/discussions/5629#discussioncomment-14447960"}}}
Discussion options

You must be logged in to vote

Sorry, haven't had time to figure out the minimum reproduction (our project is quite large), but I managed to find a couple of fixes/workarounds, one of which was intended for Vue 2 even though we are on the latest Vue 3 and vue-tsc. It's unclear which one(s) are the "actual" cause(s), but these helped:

Manually type mapState, mapGetters, etc.

For computed variables / component properties & methods issue, this worked well for some cases (for example in a component library where the final type for your Vuex or Pinia store can't be specified yet: https://stackoverflow.com/a/70983629/2836299

Use of deprecated computed cache invalidation

Trying to invalidate cache for computed variables as de…

Replies: 1 comment 3 replies

Comment options

You must be logged in to vote
3 replies
@heyakyra
Comment options

@KazariEX
Comment options

KazariEX Sep 8, 2025
Collaborator

@heyakyra
Comment options

Answer selected by heyakyra
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet
3 participants