Skip to content

Commit dbdf1ca

Browse files
ktsnchrisvfritz
authored andcommitted
Add Vue + TypeScript guide (#649)
* add vue + typescript guide * add introduction of typescript guide * add a caveat of official declaration files * improve typescript guide by reviews * fix the description of typescript again * revise and reorganize typescript doc * Update strong to static in typescript guide
1 parent 788e6fc commit dbdf1ca

File tree

7 files changed

+103
-5
lines changed

7 files changed

+103
-5
lines changed

src/images/typescript-type-error.png

66.2 KB
Loading

src/v2/guide/comparison.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Comparison with Other Frameworks
33
type: guide
4-
order: 28
4+
order: 29
55
---
66

77
This is definitely the most difficult page in the guide to write, but we do feel it's important. Odds are, you've had problems you tried to solve and you've used another library to solve them. You're here because you want to know if Vue can solve your specific problems better. That's what we hope to answer for you.

src/v2/guide/join.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Join the Vue.js Community!
33
type: guide
4-
order: 29
4+
order: 30
55
---
66

77
Vue's community is growing incredibly fast and if you're reading this, there's a good chance you're ready to join it. So... welcome!

src/v2/guide/migration-vue-router.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Migration from Vue Router 0.7.x
33
type: guide
4-
order: 26
4+
order: 27
55
---
66

77
> Only Vue Router 2 is compatible with Vue 2, so if you're updating Vue, you'll have to update Vue Router as well. That's why we've included details on the migration path here in the main docs. For a complete guide on using the new Vue Router, see the [Vue Router docs](http://router.vuejs.org/en/).

src/v2/guide/migration-vuex.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Migration from Vuex 0.6.x to 1.0
33
type: guide
4-
order: 27
4+
order: 28
55
---
66

77
> Vuex 2.0 is released, but this guide only covers the migration to 1.0? Is that a typo? Also, it looks like Vuex 1.0 and 2.0 were released simultaneously. What's going on? Which one should I use and what's compatible with Vue 2.0?

src/v2/guide/migration.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Migration from Vue 1.x
33
type: guide
4-
order: 25
4+
order: 26
55
---
66

77
## FAQ

src/v2/guide/typescript.md

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---
2+
title: TypeScript Support
3+
type: guide
4+
order: 25
5+
---
6+
7+
## Official Declaration Files
8+
9+
A static type system can help prevent many potential runtime errors, especially as applications grow. That's why Vue ships with [official type declarations](https://github.com/vuejs/vue/tree/dev/types) for [TypeScript](https://www.typescriptlang.org/) - not only in Vue core, but also [for Vue Router](https://github.com/vuejs/vue-router/tree/dev/types) and [for Vuex](https://github.com/vuejs/vuex/tree/dev/types) as well.
10+
11+
Since these are [published on NPM](https://unpkg.com/vue/types/), you don't even need external tools like `Typings`, as declarations are automatically imported with Vue. That means all you need is a simple:
12+
13+
``` ts
14+
import Vue = require('vue')
15+
```
16+
17+
Then all methods, properties, and parameters will be type checked. For example, if you misspell the `template` component option as `tempate` (missing the `l`), the TypeScript compiler will print an error message at compile time. If you're using an editor that can lint TypeScript, such as [Visual Studio Code](https://code.visualstudio.com/), you'll even be able to catch these errors before compilation:
18+
19+
![TypeScript Type Error in Visual Studio Code](/images/typescript-type-error.png)
20+
21+
### Compilation Options
22+
23+
Vue's declaration files require the `--lib DOM,ES2015.Promise` [compiler option](https://www.typescriptlang.org/docs/handbook/compiler-options.html). You can pass this option to the `tsc` command or add the equivalent to a `tsconfig.json` file.
24+
25+
### Accessing Vue's Type Declarations
26+
27+
If you want to annotate your own code with Vue's types, you can access them on Vue's exported object. For example, to annotate an exported component options object (e.g. in a `.vue` file):
28+
29+
``` ts
30+
import Vue = require('vue')
31+
32+
export default {
33+
props: ['message'],
34+
template: '<span>{{ message }}</span>'
35+
} as Vue.ComponentOptions<Vue>
36+
```
37+
38+
## Class-Style Vue Components
39+
40+
Vue component options can easily be annotated with types:
41+
42+
``` ts
43+
import Vue = require('vue')
44+
45+
// Declare the component's type
46+
interface MyComponent extends Vue {
47+
message: string
48+
onClick (): void
49+
}
50+
51+
export default {
52+
template: '<button @click="onClick">Click!</button>',
53+
data: function () {
54+
return {
55+
message: 'Hello!'
56+
}
57+
},
58+
methods: {
59+
onClick: function () {
60+
// TypeScript knows that `this` is of type MyComponent
61+
// and that `this.message` will be a string
62+
window.alert(this.message)
63+
}
64+
}
65+
// We need to explicitly annotate the exported options object
66+
// with the MyComponent type
67+
} as Vue.ComponentOptions<MyComponent>
68+
```
69+
70+
Unfortunately, there are a few limitations here:
71+
72+
- __TypeScript can't infer all types from Vue's API.__ For example, it doesn't know that the `message` property returned in our `data` function will be added to the `MyComponent` instance. That means if we assigned a number or boolean value to `message`, linters and compilers wouldn't be able to raise an error, complaining that it should be a string.
73+
74+
- Because of the previous limitation, __annotating types like this can be verbose__. The only reason we have to manually declare `message` as a string is because TypeScript can't infer the type in this case.
75+
76+
Fortunately, [vue-class-component](https://github.com/vuejs/vue-class-component) can solve both of these problems. It's an official companion library that allows you to declare components as native JavaScript classes, with a `@Component` decorator. As an example, let's rewrite the above component:
77+
78+
``` ts
79+
import Vue = require('vue')
80+
import Component from 'vue-class-component'
81+
82+
// The @Component decorator indicates the class is a Vue component
83+
@Component({
84+
// All component options are allowed in here
85+
template: '<button @click="onClick">Click!</button>'
86+
})
87+
export default class MyComponent extends Vue {
88+
// Initial data can be declared as instance properties
89+
message: string = 'Hello!'
90+
91+
// Component methods can be declared as instance methods
92+
onClick (): void {
93+
window.alert(this.message)
94+
}
95+
}
96+
```
97+
98+
With this syntax alternative, our component definition is not only shorter, but TypeScript can also infer the types of `message` and `onClick` without explicit interface declarations. This strategy even allows you to handle types for computed properties, lifecycle hooks, and render functions. For full usage details, see [the vue-class-component docs](https://github.com/vuejs/vue-class-component#vue-class-component).

0 commit comments

Comments
 (0)