Vetur: templateInterpolationService does not work in Nuxt projects

Created on 15 Sep 2019  Â·  9Comments  Â·  Source: vuejs/vetur

  • [x] I have searched through existing issues
  • [x] I have read through docs
  • [x] I have read FAQ

Info

  • Platform: Linux
  • Vetur version: 0.22.3
  • VS Code version: 1.38.1

Problem

I set "vetur.experimental.templateInterpolationService" to true in my settings.
Interpolation does not work on vue template inside a Nuxt projet.
It however works in a standart Vue project.

Reproducible Case

  • npx create-nuxt-app test and choose all default with jsconfig enabled
  • Replace pages/index.vue text by:
<template>
  <v-layout>
    <p>{{ helloWorld }}</p>
  </v-layout>
</template>

<script>
export default {
  name: 'Accueil',
  data() {
    return {
      helloWorld: 'test'
    }
  },
  head() {
    return {
      title: 'Accueil'
    }
  }
}
</script>
  • Now the interpolation doesn't work, it is probably due to custom methods used by nuxt such as head().
question

Most helpful comment

Yes, your assumption is correct. Since template interpolation service uses TypeScript type of Vue component, it needs to be properly typed.
You should install @nuxt/types and read it in jsconfig.json.

{
  "include": [
    "./src/**/*",
    "./node_modules/@nuxt/types/index.d.ts"
  ]
}

All 9 comments

Yes, your assumption is correct. Since template interpolation service uses TypeScript type of Vue component, it needs to be properly typed.
You should install @nuxt/types and read it in jsconfig.json.

{
  "include": [
    "./src/**/*",
    "./node_modules/@nuxt/types/index.d.ts"
  ]
}

Oh thanks ! I couldn't find this info anywhere :/
Now I have this error on every variables :
Property 'focus' does not exist on type 'CombinedVueInstance & Vue, object, object, object, Record>'.Vetur(2339)

But I can understand that the feature is still experimental !

Hi @lvaroqui - that error sounds like the majority of the error types that you'll see with TS Vue components. The downside of the circular references in Vue component instances (e.g. lots of this.something properties reference other this.somethingElse properties) is that when one thing goes wrong in the component typing, quickly everything goes wrong.

A very common case is that if your computed props don't have return type annotations, Vue will have a tough time inferring the overall type of the component. So try starting with adding those, e.g.

computed: {
  myComputedProp(): string {
    return 'hello'
  }
}

and see if that clears up a lot of the type errors

I do not actually use Typescript in my components but I will try to convert them, I don't have a lot for now. Thanks for the advice :)

Oh, totally understand - yeah, in my limited experience thus far, I think templateInterpolationService is unlikely to work effectively in non-TypeScript components; I opened #1427 to hopefully enable an option where the interpolation is only attempted on lang="ts" components

I'd say template interpolation generally works as well in Nuxt as plain Vue. One problematic case though, and one that seems to be the problem here specifically, is the head component option. That one breaks this everywhere if not annotated explicitly.

Use simple repro from author of this issue to reproduce.

Things will work fine if head is annotated:

  /** @return {import('vue-meta').MetaInfo} */
  head() {
    return {
      title: 'Accueil'
    }
  }

I was wondering if that is maybe because type is wrong for head. It's currently this:

declare module 'vue/types/options' {
  interface ComponentOptions<V extends Vue> {
    // ...
    head?: MetaInfo | (() => MetaInfo)
    // ..
  }
}

I've tried adding this, but that didn't help:

declare module 'vue/types/options' {
  interface ComponentOptions<V extends Vue> {
    // ...
    head?: MetaInfo | ((this: V) => MetaInfo)
    // ..
  }
}

So I'm wondering if there is some hardcoding in Vetur that makes things work for other component options, that could be also applied to this one. Or there could maybe be a setting to define that per-project.

(To summarize, adding return annotation solves the problem but it gets repetitive and seems redundant so ideally, things should just work without it.)

That's the restriction of TypeScript and the current Vue's typing.
https://vuejs.org/v2/guide/typescript.html#Annotating-Return-Types

I'm not sure if we can handle it in Vetur. I don't think we can hook some custom processing in type inference.

In any cases, the composition API in Vue v3 will get rid of this problem since it does not use this and type inference will be simpler.

That's the restriction of TypeScript and the current Vue's typing.

Well, then I guess there is no bug here.

In any cases, the composition API in Vue v3 will get rid of this problem

Personally I do plan to switch to TS eventually but this is about JS + JSDoc annotations. :)

Thanks for everyone answering questions — I'll look into #1427.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yoyoys picture yoyoys  Â·  3Comments

gabrielboliveira picture gabrielboliveira  Â·  3Comments

deangoku picture deangoku  Â·  3Comments

13029852933 picture 13029852933  Â·  3Comments

thibautguedou3 picture thibautguedou3  Â·  3Comments