0

Please see this minimum example:

import Vue from 'vue';

Vue.extend({
  data() {
    return {
      name: 'Amy',
    };
  },
  methods: {
    hello() {
      return this.name; // TypeScript knows it's string
    },
    hello2: (function() {
      // This is a IIFE
      return function() {
        return this.name; // TypeScript doesn't know this right now
      };
    })(),
  },
});

enter image description here

Off topic: I was creating a factory pattern for Vue components, in order to do that, I need to attach IIFE for methods, I simplify the example like above.

How do I make TypeScript know the this in that IIFE?

Update:

The purpose of doing these things is because I want to create a mixin utility, which can configure to be debounced or not, take mouse position mixin as an example

import Vue from 'vue';
import debounce from 'lodash/debounce';

type mixinMousePositionAtPageType = {
  debounce?: {
    enable: boolean;
    wait?: number;
    options?: Parameters<typeof debounce>[2];
  };
};

const mixinMousePositionAtPage = (options: mixinMousePositionAtPageType) =>
  Vue.extend({
    data() {
      return {
        mixinMousePositionAtPage: {
          x: 0,
          y: 0,
        },
      };
    },
    mounted() {
      window.addEventListener('mousemove', this.__updateMousePagePosition);
    },
    destroyed() {
      window.removeEventListener('mousemove', this.__updateMousePagePosition);
    },
    methods: {
      __debouncedUpdateMousePagePosition(event: MouseEvent) {
        this.mixinMousePositionAtPage.x = event.pageX;
        this.mixinMousePositionAtPage.y = event.pageY;
      },
      __updateMousePagePosition: (function() {
        if (options.debounce && options.debounce.enable) {
          return debounce(
            this.__debouncedUpdateMousePagePosition, // this yells
            options.debounce.wait,
            options.debounce.options
          );
        }
        return this.__debouncedUpdateMousePagePosition;
      })(),
    },
  });

export { mixinMousePositionAtPage };

Joseph
  • 3,974
  • 7
  • 34
  • 67
  • Does this answer your question? [How to access the correct \`this\` inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – VLAZ Jan 10 '20 at 08:52
  • 1
    Your example is way more complex than you probably need, actually. In order to preserve this, you need to extract the object outside the call, so you can reference it by a variable name. Only in order to make the IIFE work. Perhaps it's better to avoid the IIFE in some fashion. I'm not sure what you're trying to solve with an IIFE, so I don't know the best way to remove it and still get a solution. It feels like [an XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – VLAZ Jan 10 '20 at 08:56
  • TypeScript doesn't know it because `this` would simply be wrong. It will not refer to the enclosing object but to the global one *or* to `undefined` (depending on whether the code is strict mode or not). – VLAZ Jan 10 '20 at 08:57
  • What's the purpose of this IIFE? As it was suggested, you may have XY problem. – Estus Flask Jan 10 '20 at 08:57
  • I have included my actual usage. – Joseph Jan 10 '20 at 09:06
  • IIFE isn't a valid option in this case, it should be written in some other way. `this` is `window` or `undefined` in this context, there's really no `this.__debouncedUpdateMousePagePosition`. – Estus Flask Jan 10 '20 at 09:13
  • I think I got it, thank you – Joseph Jan 10 '20 at 09:15

0 Answers0