Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'inject' Properties are not added to the CombinedVueInstance type definition #8969

Open
StormBurpee opened this issue Oct 19, 2018 · 8 comments

Comments

@StormBurpee
Copy link

Version

2.5.17

Reproduction link

https://codesandbox.io/s/rr18r3vm9p

Steps to reproduce

  1. Copy Minimal reproduction link into a local environment, and run the webpack compilation process.

OR

  1. Initialize a vue vm
let vm = new Vue({
    el: "#app",
    render: (h: any) => h(someComponent, {}),
    provide: { service: { something: "Hello, World" } }
});
  1. Try and access service in a SFC
export default Vue.extend({
    name: "someComponent",
    inject: ["service"],
    data() {
        return {
            accessService: this.service.something // Property 'service' does not exist on type CombinedVueInstance...
        }
    }
});

What is expected?

When declaring injections in a component in typescript, you should be able to access the injection with this.injection

What is actually happening?

When accessing an injection in a vue single file component, it is currently throwing an error during the webpack compilation process, stating that the injection Property 'injection' does not exist on type 'CombinedVueInstance<Vue...


Please note: that the link to minimal reproduction won't show the error logs from the webpack compiling, as it will compile successfully, but with errors. This will need to be tested in a local environment to see what is happening.

As this is in typescript, we're currently using Webpack to compile it to a single file, and then use this on our application.

The compilation will complete successfully, however will print multiple errors to the console after compiling, about not being able to access properties, etc. When running in the browser it works successfully.

We've dug around in the vue/types folder, and to the best of our knowledge think that Inject should be a part of the type DataDef or something of this sort.

Is there possibly a temporary workaround that we can use to avoid having these errors, until a fixed release is proposed?

@XLearner
Copy link

Yep, I come across a similar question. I have written the property "provide" in father vue-component and have used "inject" in son vue-component, but the chrome console show: [Vue warn]: Injection "color" not found. Here is my sectional code.

/********** parent /
...
export default {
name: "father",
provide: {
color: 'blue'
},
components: {
son
},
...
/
son **********/
...
export default {
name: 'pagesTable',
inject: ['color'],
mounted(){
console.log(this.color);
}
}
...

And then
image

@filimon-danopoulos-stratsys

Any news on this?

@klinkby
Copy link

klinkby commented Dec 16, 2019

Issue open >1 year. Does that mean DI is not supported with TypeScript?

@wllmsash
Copy link

I'm working around this by modifying Vue in my component. Example:

// main.ts

import Vue from 'vue';
import App from './App.vue';

export interface Collection {
  dog: string;
  cat: number;
  cow: boolean;
}

const myCollection: Collection = {
  dog: 'dog',
  cat: 0,
  cow: false,
};

export const myServices = {
  api: 'api',
  auth: {
    do: 'something',
  },
};

new Vue({
  render: h => h(App),
  provide: {
    ...myCollection,
    ...myServices,
  },
}).$mount('#app');
// src/helpers/vue.ts

import { VueConstructor } from 'vue';

export function makeInjector<TProvider>() {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  return function<V extends Vue, K extends keyof TProvider>(v: VueConstructor<V>, properties: K[]) {
    return v as VueConstructor<V & Pick<TProvider, K>>;
  };
}

export function makePropertySelector<TProvider>() {
  return function<K extends keyof TProvider>(properties: K[]) {
    return properties;
  };
}
// src/components/my-component.vue

import Vue from 'vue';
import { makeInjector, makePropertySelector } from '../helpers/vue';
import { Collection, myServices } from '../main';

// use a type ...
const collectionPropInjector = makeInjector<Collection>();

// ... or typeof
const serviceInjector = makeInjector<typeof myServices>();

// use propertySelector to reuse across injector and inject
const injectServices = makePropertySelector<typeof myServices>();
const services = injectServices(['auth']);

// add properties from one or many types to this Vue instance ...
export default serviceInjector(collectionPropInjector(Vue, ['dog', 'cat']), services).extend({
  // ... and inject properties as normal here
  inject: ['dog', 'cat', ...services],
  created() {
    console.log(this.dog); // 'dog'
    console.log(this.cat); // 0
    console.log(this.cow); // undefined

    console.log(this.api); // undefined
    console.log(this.auth.do); // 'something'
  },
});

Works with VSCode Intellisense as well.

@shivam-deepsource
Copy link

Been facing the same issue with my TypeScript project. I resorted to use $parent and methods in subcomponents to be accessed in descendent component. Would really appreciate if I could use DI with TypeScript.

@fgarciajulia
Copy link

A temporary workaround is define it in data as optional.
That worked for me.

interface IData {
  accessService: Something
  service?: Service // injected property
}

export default Vue.extend({
  name: 'someComponent',
  inject: ['Service'],
  data(): IData {
    return {
      accessService: this.service?.something
    }
  },

@niraj-nagtilak1990
Copy link

niraj-nagtilak1990 commented Aug 3, 2022

I had to workaround this by defining fake prop for injected property. I am on vue js 2.6.13 version, I hope this gets fixed in new version.

Before

image

After workaround with fake prop

image

@XLearner
Copy link

XLearner commented Oct 11, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants