Subscribe on changes!

Typescript definition of 'mounted' in Options API should support Promise<void> signature

avatar
May 12th 2022

Link to minimal reproduction

https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBsYW5nPVwidHNcIj5cbmltcG9ydCB7IGRlZmluZUNvbXBvbmVudCB9IGZyb20gJ3Z1ZSc7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbXBvbmVudCh7XG4gIG5hbWU6ICdMb2dvdXQnLFxuICBkYXRhICgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbXNnOiAnYmx1ZSdcbiAgICB9O1xuICB9LFxuICBhc3luYyBtb3VudGVkICgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHR0aGlzLm1zZyA9ICd3b3JsZCc7XG4gIH1cbn0pO1xuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cbiAgPGgxPnt7IG1zZyB9fTwvaDE+XG4gIDxpbnB1dCB2LW1vZGVsPVwibXNnXCI+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==

Steps to reproduce

We have been able to use the mounted method in an async manner (in non-TS and less strict ESLint envs), such as for making remote API calls. When using Typescript we get told that mounted can't return a Promise. Code example below:

import { defineComponent } from 'vue';

export default defineComponent({
  name: 'Logout',
  async mounted (): Promise<void> {
  }
}

BTW looking at https://github.com/vuejs/vue/blob/dev/types/options.d.ts I do see no Promise<void> support.

What is expected?

Based on behaviour in non-Typescript, I would expect the TS definition to support a definition as:

  mounted?(): void | Promise<void>;

BTW we only recently noticed this because of increased strictness of our linter.

What is actually happening?

Linting failure, with the following message:

Promise-returning function provided to property where a void return was expected. eslint@typescript-eslint/no-misused-promises

System Info

System:
    OS: macOS 12.3.1
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 1.43 GB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.6.0 - ~/.nvm/versions/node/v16.6.0/bin/node
    Yarn: 1.22.10 - ~/npm/bin/yarn
    npm: 7.19.1 - ~/.nvm/versions/node/v16.6.0/bin/npm
  Browsers:
    Brave Browser: 92.1.28.105
    Chrome: 102.0.5005.49
    Chrome Canary: 103.0.5058.0
    Firefox: 99.0.1
    Safari: 15.4
    Safari Technology Preview: 15.4
  npmPackages:
    vue: ^3.0.0 => 3.2.33

Any additional comments?

Right now the solution I have is simply to disable the eslint check for the line.

Additionally, this following example, albeit Vue 2, shows axios being called, further reinforcing the need for mounted to be returning a promise:

https://v2.vuejs.org/v2/cookbook/using-axios-to-consume-apis.html?redirect=true

Also wondering if other methods, such as created() should also be supporting Promises in their Typescript definition?