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
};
})(),
},
});
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 };