ffxsam / vue-typescript-cookbook Goto Github PK
View Code? Open in Web Editor NEWRecipes to demystify Vue + TypeScript
Recipes to demystify Vue + TypeScript
Not adding computed return type annotation is very common mistake and I think it's worth to add a section about this, something like
computed: {
// bad
foo () {
return this.baz + 1;
}
// good
bar (): number {
return this.baz + 1;
}
}
You hit the nail on it's head with your guide here. There is so much useful information my team and I missed from the official documentation, with no clear answers on the web, what the approach is to solve these common problems.
Did you ever consider trying to push this information as pull request to the Vue 2.0 documentation?
The helper mapActions
seems to suffer from the same problem as the problem described with mapState
and mapGetters
. I'm betting that the solution described there also works for mapActions
, but I'm not exactly sure what form it should take.
For instance, marking the action as any
will silence the error, but I feel like there's a more correct type for actions. It might be good to have an example of the right type for actions.
import Vue, {VueConstructor} from 'vue';
import {mapActions} from 'vuex';
// Without this interface you get the following error
// 19:26 Property 'myAction' does not exist on type 'CombinedVueInstance<Vue, unknown, { doIt(): void; }, unknown, Readonly<Record<never, any>>>'.
interface VuexBindings {
myAction: any;
}
export default (Vue as VueConstructor<Vue & VuexBindings>).extend({
created() {
console.log(this.myAction);
},
methods: {
doIt() {
console.log("doing a thing");
},...mapActions(['myAction'])
},
});
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
myAction(store) {
console.log("doing action");
}
},
modules: {
},
});
How do I annotate dependencies using provide
/ inject
?
// provider.ts
import Vue from "vue";
export default Vue.extend({
provide() {
return {
foo: "Hello world"
};
},
});
// consumer.ts
import Vue from "vue";
export default Vue.extend({
inject: ["foo"],
methods: {
method() {
console.log(this.foo);
},
},
});
For now, my workaround is to declare the property globally:
// main.d.ts
declare module "vue/types/vue" {
interface Vue {
foo: string;
}
}
I also tried the following, but it didn't seem to work:
// consumer.ts
import Vue, { VueConstructor } from "vue";
interface Inject {
foo: string;
}
export default (Vue as VueConstructor<Vue & Inject>).extend({
inject: ["foo"],
methods: {
method() {
console.log(this.foo);
},
},
});
When I try to call a method from my Vue component methods in the created hook, it tells me it does not exist. Do I need to add the method to an interface and extend it or is there something simpler.
Here's the example:
export default Vue.extend({
created() {
this.fetchData(); // VSCode tells me this method does not exist.
},
methods: {
fetchData() {
...
},
},
});
If you're mixins is still in js and you wanted to include it on your ts component, it's better to create interface as the type of everything in the mixins will become any and break the type annotations on your component
VueConstructor<
Vue
& IYourMixins
>
instead of
VueConstructor<
Vue
& InstanceType<typeof YourMixins>
>
I tried out the How do I make a function outside the scope of the Vue component have the correct this
context? recipe without success:
Line 8:
TS2502: 'this' is referenced directly or indirectly in its own type annotation.Line 18:
TS7022: 'HelloWorld' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
HelloWorld.vue
:
<template>
<div />
</template>
<script lang="ts">
import Vue from "vue";
type ValidatorFunc = (this: InstanceType<typeof HelloWorld>) => Function;
const validator: ValidatorFunc = function () {
return () => {
if (this.name === "bad") {
// do something
}
};
};
const HelloWorld = Vue.extend({
data() {
return {
name: "",
locations: [] as string[],
somethingHandler: {
trigger: "blur",
handler: validator.bind(this),
},
};
},
});
export default HelloWorld;
</script>
Background: I thought I needed this for a _.debounce
d method:
<template>
<div />
</template>
<script lang="ts">
import Vue from "vue";
import { debounce } from "lodash";
type HandlerFunc = (this: InstanceType<typeof HelloWorld>) => void;
const handler: HandlerFunc = function () {
console.log(this.$el);
};
const HelloWorld = Vue.extend({
methods: {
handler: debounce(handler.bind(this)),
},
});
export default HelloWorld;
</script>
Meanwhile, I came across a workaround a.k.a. better solution in the Vue.js forum: https://forum.vuejs.org/t/lodash-debounce-not-working-when-placed-inside-a-method/86334/5
<template>
<div />
</template>
<script lang="ts">
import Vue from "vue";
import { debounce } from "lodash";
export default Vue.extend({
created() {
this.handler = debounce(this.handler);
},
methods: {
handler() {
console.log(this.$el);
},
},
});
</script>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.