Skip to content
This repository has been archived by the owner on Jun 29, 2021. It is now read-only.

Typescript support #5

Open
ChrisShank opened this issue Jan 4, 2020 · 16 comments
Open

Typescript support #5

ChrisShank opened this issue Jan 4, 2020 · 16 comments

Comments

@ChrisShank
Copy link

I am adding Typescript and I am not certain what the shim for *.vue files should be? My best guess is:

// shims-vue.d.ts
declare module '*.vue' {
  import { Component } from 'vue'
  const component: Component
  export default component
}

does anyone know if this is correct?

@yyx990803
Copy link
Member

Since *.vue files only export object-format components in v3, you can use ComponentOptions instead Component (the latter is a union type which includes FunctionalComponent)

@Timmitry
Copy link

@ChrisShank Do you have a working setup for Typescript? If so, would you be willing to share it? I struggled with including support for .ts files…

@ChrisShank
Copy link
Author

ChrisShank commented Feb 28, 2020

Hi @Timmitry see my fork!

Edit : also added vue-router@next and vuex@next to my fork!

@Timmitry
Copy link

@ChrisShank Thanks a lot, adding your changes worked like a charm 🎉 Now only vetur needs to remove the The template root requires exactly one element.-error, but I can ignore that 😉

@bekalshenoy
Copy link

How To Add JSX Support

@onx2
Copy link

onx2 commented Apr 29, 2020

@ChrisShank Thanks for the fork, it is exactly what I was looking for!! 😄

Idk if you saw this too but I was receiving this error in router.ts on your fork:

[tsl] ERROR in /home/.../src/router.ts(8,18)
      TS2322: Type 'new () => ComponentPublicInstance<{}, { store: any; }, {}, {}, {}, Record<string, any>, VNodeProps>' is not assignable to type 'undefined'.

But it seems to work fine if I change the routes to async functions like:

routes: [
  { path: '/', component: async () => Home, name: 'home' },
  { path: '/about', component: async () => About, name: 'about' },
],

@ChrisShank
Copy link
Author

@bekalshenoy JSX seems to be a work in progress right now...
https:/vuejs/vue-next#official-libraries-vue-3-support-status

@ChrisShank
Copy link
Author

ChrisShank commented Apr 29, 2020

@onx2 Unfortunately I haven't been able to reproduce that error. I just updated the dependencies of my fork (most notably to [email protected]) so maybe that could fix it? Here is the commit. Let me know if there is anything else I can do! 😄

@deemaxx
Copy link

deemaxx commented May 7, 2020

@Timmitry here is a TS version of this repo. I did not use JSX, however. Just plain render functions. Just an idea. https:/deemaxx/vue-next-webpack-typescript

@janispritzkau
Copy link

I get an error when I use a imported component as a type.

import { defineComponent, ref } from "vue"
import HelloWorld from "./components/HelloWorld.vue"

export default defineComponent({
  components: { HelloWorld },
  setup() {
    const componentRef = ref<HelloWorld | null>(null)
  }
})

'HelloWorld' refers to a value, but is being used as a type here.

@ChrisShank
Copy link
Author

@janispritzkau HelloWorld is a value here. typeof HelloWorld will give you the type of that Vue component.

@janispritzkau
Copy link

janispritzkau commented Jun 8, 2020

I found a solution but it feels a bit like a hack.

const componentRef = ref<InstanceType<typeof HelloWorld> | null>(null)

@ChrisShank typeof only gives you the constructor type.

@janispritzkau
Copy link

I noticed that I was only able to directly use the components as a type because I was using class components.

I also ran into another problem that you can't self reference a component, or have a child component, that has a type reference of it's parent which has the child component defined in it's components.

@vsimko
Copy link

vsimko commented Jun 19, 2020

I almost got it working using the following approach:

<template>
  <hello-world ref="hello">
</template>

<script lang="ts">
import { ComponentOptions } from 'vue';
import HelloWorld from "./components/HelloWorld.vue"

// helper function to attach type to a vue reference
function typesafeComponentRef<T>(elementRef: Element, vueComponent: T) {
  type ExtractVueComponentType<X> = X extends ComponentOptions<any, infer Data, any, any, any, any> ? Data : never;
  return elementRef as ExtractVueComponentType<typeof vueComponent>;
}

export default defineComponent({
  setup(props, context) {
    watchEffect(() => {
      const helloWorld = typesafeComponentRef(context.refs.hello, HelloWorld)
      // here code completion works in Intellij
      // but the type of helloWorld is always `unknown`
      const x = helloWorld.someDataVariable // autocompleted someDataVariable
      ...
    });
  }
});
</script>

@way2ex
Copy link

way2ex commented Jul 25, 2020

@ChrisShank Thanks a lot, adding your changes worked like a charm 🎉 Now only vetur needs to remove the The template root requires exactly one element.-error, but I can ignore that 😉

you can set this for vetur "vetur.validation.template": false
see this vuejs/vetur#1976

Also I create a project with vue3 and webpack, you can take a look here

@DrMabuse23
Copy link
Contributor

@ChrisShank Thanks a lot, adding your changes worked like a charm 🎉 Now only vetur needs to remove the The template root requires exactly one element.-error, but I can ignore that 😉

you can set this for vetur "vetur.validation.template": false
see this vuejs/vetur#1976

Also I create a project with vue3 and webpack, you can take a look here

thx for your link can you translate your comments in the webpack.config in english please ?

HomyeeKing added a commit to HomyeeKing/vitesse that referenced this issue Feb 4, 2021
see vuejs/vue-next-webpack-preview#5 (comment)

but we may lose the ability to  locate the `.vue` file in `.ts`
antfu pushed a commit to antfu-collective/vitesse that referenced this issue Feb 5, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants