typescript: The type definition of `$loading` conflicts with Buefy's one

Version

v2.4.0

Reproduction link

https://github.com/iwata/codesandbox-nuxt

Steps to reproduce

$ git clone git@github.com:iwata/codesandbox-nuxt.git
$ yarn install
$ yarn dev

What is expected ?

No type checking errors

What is actually happening?

It shows this error:

ERROR in /Users/iwata/.go/src/github.com/iwata/codesandbox-nuxt/node_modules/@nuxt/vue-app/types/index.d.ts(73,18):
TS2430: Interface 'NuxtApp' incorrectly extends interface 'Vue'.
  Types of property '$loading' are incompatible.
    Property 'open' is missing in type 'NuxtLoading' but required in type '{ open: (params: LoadingConfig) => { close: () => any; }; }'.

Additional comments?

If you import Buefy looks like plugins/buefy.ts, it declares $loading for Vue instance. https://github.com/buefy/buefy/blob/dev/types/index.d.ts#L10 So NuxtApp extends the Vue, therefore $loading conflicts. https://github.com/nuxt/nuxt.js/blob/v2.4.0/packages/vue-app/types/index.d.ts#L73-L74

<div align="right">This bug report is available on Nuxt community (#c8559)</div>

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 8
  • Comments: 40 (13 by maintainers)

Commits related to this issue

Most upvoted comments

For now i added the following to my tsconfig.json:

"compilerOptions": {
    "skipLibCheck": true
}

We will change it to $nuxt.$loading this.$nuxt.$progress in Nuxt 3 ☺️

I have this issue with Element-ui also. Are there any clarifications on this? Maybe a temporary fix?

Well, there is the same issue for ElementUI if i’m right.

I don’t know what we’re supposed to do, both of frameworks (Nuxt & Buefy) are setuping the same variable so 😬

@manniL WDYT ?

The only solution could be to have the $loading definition outside of @nuxt/vue-app to avoid that but it sounds weird to not have it inside.

@P-de-Jong’s solution works for me

This also worked for me, however, it seems to be more of a work-around than a solution.

I believe this is not a Nuxt-ts or element-ui issue @iwata @hartmut-co-uk may you need to define the $loading type

import {ElLoading} from 'element-ui/types/loading'
import {ElMessage} from 'element-ui/types/message'
import {ElMessageBox} from 'element-ui/types/message-box'
import {ElNotification} from 'element-ui/types/notification'
declare module 'vue/types/vue' {
  interface Vue {
     readonly $loading: typeof ElLoading.service
     // maybe you will use these things also
     readonly $alert: typeof ElMessageBox.alert
     readonly $confirm: typeof ElMessageBox.confirm
     readonly $message: ElMessage
     readonly $msgbox: ElMessageBox
     readonly $notify: ElNotification
     readonly $prompt: typeof ElMessageBox.prompt
  }
}

In tsconfig.json:

"compilerOptions": {
    "skipLibCheck": true
}

works for me, but hmm

Maybe instead,

"paths": {
    "element-ui": [".sink.d.ts"] // empty file
}

works, too?

@kevinmarrec Whoops. Updated my statement based on the things discused in the last meeting☺️

@manniL In fact it’s already this.$nuxt.$loading, and this.$loading is only a shortcut (AFAIK). $nuxt being a Vue instance, in any case we need to say that NuxtApp ($nuxt) extends Vue.

The issue is IMO 100% Buefy fault which is not extending but overriding Vue typedefs through https://github.com/buefy/buefy/blob/dev/types/index.d.ts#L10.

By doing this, they force the Vue instance to always have $loading property and also forcing it to be of type LoadingProgrammatic, which is wrong. Meanwhile within Nuxt, we only say that $nuxt is a Vue instance with a $loading property.

Unless we force us to change the name from $loading to something else, there won’t be workarounds. Buefy (and ElementUI) should highly initiate a breaking change which namespace their properties.

@bichikim The issue is that it’s a naming collision between the $loading from nuxt and the one from ElementUI/Buefy.

That would be ideal although legacy support for the current Vue 2 is a long term goal for the team I believe.

Maybe it would be worth to start thinking in terms of the composition API? If Nuxt and/or ElementUI provided this stuff through a composable there would be no problem.

For example, I’m relying on a custom made const nuxt = useNuxtContext() composable. I access everything related to Nuxt using that.

Has anyone found an official workaround (that may already present in this thread) that currently works ?

@ChangJoo-Park

Since new TS support, NuxtApp is now accessible via

import { NuxtApp } from '@nuxt/types/app/index'