Unable to use component's method in TypeScript
0140454 opened this issue · comments
Environment
Packages
- ts-loader v8.2.0
- vue v2.6.14
- @vue/composition-api v1.4.0
Shims
shims-vue.d.ts
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
Description
There is a ref in my template to call method defined in child component.
In setup()
, I use child = ref<InstanceType<typeof ChildComponent>>()
to declare it and use it in onMounted()
callback function later.
However, ts-loader outputs the following errors while compiling:
ERROR in /project/src/pages/Demo.vue.ts
[tsl] ERROR in /project/src/pages/Demo.vue.ts(15,20)
TS2339: Property 'work' does not exist on type 'CombinedVueInstance<Vue, object, object, object, Record<never, any>>'.
Is it possible that shims-vue.d.ts makes ts-loader not infer type correctly?
Example Code
ChildComponent.vue
<template>
<div />
</template>
<script lang="ts">
import { defineComponent } from '@vue/composition-api'
export default defineComponent({
name: 'Demo',
setup() {
const work = () => {
console.log('work')
}
return { work }
},
})
</script>
<style lang="scss" module></style>
Demo.vue
<template>
<child-component ref="child" />
</template>
<script lang="ts">
import { defineComponent, onMounted, ref } from '@vue/composition-api'
import ChildComponent from './ChildComponent.vue'
export default defineComponent({
name: 'Demo',
setup() {
const child = ref<InstanceType<typeof ChildComponent>>()
onMounted(() => {
child.value!.work()
})
return { child }
},
})
</script>
<style lang="scss" module></style>
Please
- remove
declare module '*.vue'
- disable ts type checking in webpack
- and use vue-tsc
see
https://github.com/xiaoxiangmoe/vue2-vuecli-demo/blob/master/src/shims-vue.d.ts#L1
If I remove declare module '*.vue'
in shims-vue.d.ts
, vue-tsc will complain TS7016: Could not find a declaration file for module
.
Therefore, I keep shims-vue.d.ts
and continue item 2 and 3 you mentioned.
Since I use webpack4 and ts-loader now, I perform the following steps:
- Add
transpileOnly: false
in ts-loader options - Follow Volar tutorial, add
@vue/runtime-dom
and set necessary options to avoid JSX errors in template block
Currently, vue-tsc is responsible for type checking, and webpack is for other works. In the meanwhile, IDE with Volar extension works great.
@xiaoxiangmoe Thanks for your help. But if there is wrong in the above steps, please continue giving me some advice.
Or, this issue can be closed.
Can you give me a repo for reproduction?
While making a repository for reproduction, I found that TS7016 error generated because included files are not written in TypeScript.
My project contains Vue components written in JavaScript or TypeScript.
Those files, who don't have script
block or there is no lang="ts"
in script
tag, will make vue-tsc generate TS7016 error.
Repository: https://github.com/0140454/vue-test
Is it possible to use JavaScript and TypeScript at the same time? Just keep shims-vue.d.ts
as now?
@0140454 add "allowJs": true,
in tsconfig
After adding "allowJs": true
in tsconfig, TS7016 gone.
However, if there is a event handler or variable in attribute, vue-tsc generate TS2304: Cannot find name
error even though I have exposed them in setup()
.
This error is not generated when
allowJs
is false.
The repository has been updated for TS2304.
Sorry for confusion. But TS2304 errors are reported in ts .vue
files.
The js .vue
files seems to be fine to vue-tsc.
Maybe you should add types for js .vue
files, or use defineComponent to wrap object.
@xiaoxiangmoe Thanks for your hint.
After I use Vue.extend
to wrap object exported in js .vue
file, it passes vue-tsc check.
why not use defineComponent?
Oh, sorry that I forget updating.
defineComponent
and Vue.extend
both can eliminate TS2304. I just try Vue.extend
first, and I have changed it to defineComponent
now.