VS Code Typescript gives error "property does not exists" in Vuejs Project

Viewed 543

I have a Vuejs project in Typescript. Project compiles and runs perfectly without error. But the TS linter is wrong.

I'm using the component decorator in individual component files like so:

//videocard.component.vue

<script lang="ts">
    import Vue from 'vue';
    import { Component, Prop } from 'vue-property-decorator';
    import { Video } from '../interfaces/video.interface';

    @Component
    export default class VideoCardComponent extends Vue {

        @Prop() readonly video: Video;
        @Prop() readonly loading: boolean;

        created(){
            console.log(this.static_url); // !COMPLAINS HERE!
        }

        get _video(){
            return this.video
        }

        get _loading(){
            return this.loading || false;
        }
    }
</script>

Notice how I'm trying to log out property called static_url. This works because in my app.ts file, I'm setting this property like this:

//app.ts

Vue.prototype.static_url = (window as any).static_url;

I have augmented the types so static_url is a property on Vue. Like so:

// static_url.d.ts

import Vue from 'vue';

declare module 'vue/types/vue' {
    interface Vue {
      static_url: string;
    }

    interface VueConstructor {
      static_url: string
    }
}

Typescript linter does NOT complain about this property in the app.ts file, but it DOES complain about this property in the component files. Why does Typescript not recognize this property in the component files?

For completeness, here is my tsconfig.json file:

{
    "compilerOptions": {
        "target": "es5",
        "lib": ["esnext", "dom"],
        "strict": true,
        "module": "es2015",
        "noImplicitAny": false,
        "moduleResolution": "node",
        "experimentalDecorators": true,
        "strictPropertyInitialization": false
    },
    "include": [
        "assets/js/video-app/src/**/*.ts",
        "assets/js/video-app/src/**/*.d.ts",
    ]
}
2 Answers

I think you are so close, the only problem I can find is the include in tsconfig.json

Is your tsconfig.json placed outside your project so you need to have assets/js/video-app/src path?

Normally, if the tsconfig.json is in the project, include should be like below. If the include paths are incorrect, the custom type definition will not work.

"include": [
   "src/**/*.ts"
]

Can you check if static_url.d.ts is inside src directory as well.

I make a git repo to simulate your case, you can cross check with your settings.

Git Repo

If type accuracy is not important in this case, you can do:

(this as any).static_url

If type accuracy is a concern, then my 2 cents on this is that you should not be modifying the Vue prototype... not the best practice, in my opinion (Just my PTSD kicking in from debugging projects with default object prototypes being littered with non-standard properties and messing up everything and creating all kinds of nasty bugs). If you have some kind of state management framework, like Vuex, I recommend storing this data in the Vuex state.

Or hack around everything, you don't need to duplicate your data from window object to Vue.prototype

(window as any).static_url
Related