@vue/compat not working with Typescript
Version
3.2.2
Reproduction link
https://github.com/philippevezina/vue-compat-ts
Steps to reproduce
- Spin up a new project with Vue CLI on Vue 2 with Typescript
- Upgrade "vue" to "^3.1.0"
- Add "@vue/compat": "^3.1.0"
- Replace "vue-template-compile" by "@vue/compiler-sfc": "^3.1.0"
- Configure
vue.config.js
as such:
// vue.config.js
module.exports = {
chainWebpack: config => {
config.resolve.alias.set('vue', '@vue/compat')
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
return {
...options,
compilerOptions: {
compatConfig: {
MODE: 2
}
}
}
})
}
}
- Run
yarn serve
What is expected?
The project should run on Vue 3 with Typescript with Vue 2 code.
What is actually happening?
Many errors for things that should be supported by @vue/compat
such as this one:
ERROR in src/main.ts:6:5
TS2351: This expression is not constructable.
Type 'typeof import("/Users/philippevezina/Documents/test/node_modules/vue/dist/vue")' has no construct signatures.
4 | Vue.config.productionTip = false
5 |
> 6 | new Vue({
| ^^^
7 | render: h => h(App),
8 | }).$mount('#app')
9 |
I've also tried by adding the following in tsconfig.json
and it did not work:
"paths": {
"vue/*": [
"@vue/compat/*"
]
}
and
"paths": {
"vue/*": [
"node_modules/@vue/compat/*"
]
}
You need to use createApp()
. Are you following https://v3.vuejs.org/guide/migration/migration-build.html#installation with the example commits? https://github.com/vuejs/vue-hackernews-2.0/compare/migration.
Maybe it's worth adding more info in the docs repo. If you think so, a PR would be welcome 🙂
@posva
- compat does provide a default export for a Vue 2 constructor.
- The Migration guide also has migration to
createApp()
in step 7 of the install guide, while the app should run in step 5 already, where the codebase should still havenew Vue()
, I think it's reasonable to expect that TS should can deal with this. - especially since the constructor also has types:
But the default export doesn't seem to be properly typed with this. You can in fact do this in the prodived repo:
import { Vue, CompatVue } from 'vue'
(Vue as unkown as CompatVue).config.productionTip = false
Which would get rid of the error and instead shows helpful deprecation notes from the above type definition. but surely isn't the workflow we have in mind.
I first thought it might be an issue with the shims in that repo, but changing them to vue 3 style shims didnt't solve the issue.
I will reopen this as I think it should be possible to type the constructor properly.
It indeed seems to be a problem with the constructor typing. That being said, the workaround does not seem to be working on my end:
ERROR in src/main.ts:1:10
TS2305: Module '"../node_modules/vue/dist/vue"' has no exported member 'Vue'.
> 1 | import { Vue, VueCompat } from 'vue'
| ^^^
2 | import App from './App.vue'
3 |
4 | (Vue as unknown as VueCompat).config.productionTip = false
ERROR in src/main.ts:1:15
TS2305: Module '"../node_modules/vue/dist/vue"' has no exported member 'VueCompat'.
> 1 | import { Vue, VueCompat } from 'vue'
| ^^^^^^^^^
2 | import App from './App.vue'
3 |
4 | (Vue as unknown as VueCompat).config.productionTip = false
...which is why I directly deleted my comment again, seems you were faster though.
For one, the type is CompatVue
, but the real problem was that i couldn't figure out how to augment the module without killing all the other types vue
exposes.
Ohh my bad! This workaround, though not ideal, does indeed work:
import Vue, { CompatVue } from 'vue'
(Vue as unknown as CompatVue).config.productionTip = false
Here's how to get the types working (add this in a shim.d.ts
):
declare module 'vue' {
import { CompatVue } from '@vue/runtime-dom'
const Vue: CompatVue
export default Vue
export * from '@vue/runtime-dom'
}
Also added to docs
Here's how to get the types working (add this in a
shim.d.ts
):declare module 'vue' { import { CompatVue } from '@vue/runtime-dom' const Vue: CompatVue export default Vue export * from '@vue/runtime-dom' }
Also added to docs
After I try this code, other members such as createApp do not exist. It is recommended to add
import Vue from 'vue'; // this add declare module 'vue' { import { CompatVue } from '@vue/runtime-dom' const Vue: CompatVue export default Vue export * from '@vue/runtime-dom' }