You have a Vue project and you heard about all things TypeScript can help you with. You decide to start using TypeScript. Here you'll see how to do that in an approachable and pragmatic way.
In this article we'll assume you're using SFC (Single File Components), but it could work as well even if you're splitting them into multiple files. So... let's get started!
Integrating TypeScript
We're gonna start from Vue CLI Webpack's template, but it would work as well with the amazing PWA template. Don't choose to use ESLint when you're ask to:
vue init webpack my-app # or: vue init pwa my-app
cd my-app
We have to do 4 steps:
1. Create a tsconfig.json
file
Let's start with something very simple, later we'll get back to the TypeScript configuration.
{
"compilerOptions": {
"lib": ["dom", "es5", "es2015"],
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"sourceMap": true,
"allowSyntheticDefaultImports": true
}
}
The most important part is the allowSyntheticDefaultImports
setting. Since Vue types doesn't use ES2015 default exports, this setting must be set to by-pass that. You can see more info in this VSCode docs page.
Setting "module": "es2015"
would make the code tree-shakeable by producing ESM (EcmaScript Modules).
2. Add ts-loader
and webpack tweaks
Install typescript
an ts-loader
with npm:
npm i -D typescript ts-loader
Then open build/webpack.base.conf.js
, and place the following code at the beginning of module.rules
, right before than vue-loader
:
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules|vue\/src/,
loader: "ts-loader",
options: {
appendTsSuffixTo: [/\.vue$/]
}
},
...
In there, rename the entry to .ts
and add it to the extensions:
...
entry: {
app: './src/main.ts'
},
...
resolve: {
extensions: ['.ts', '.js', '.vue', '.json'],
...
3. Add es-module: true
to build/vue-loader.conf.js
That will tell vue-loader to use ES instead of CJS (CommonJS) modules, as describe in vue-loader docs:
module.exports = {
loaders: utils.cssLoaders({
sourceMap: isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap,
extract: isProduction
}),
esModule: true
}
4. Use TypeScript in files
So you must do 2 things here:
- Rename
.js
to.ts
extensions within thesrc
folder - Use
lang="ts"
on thescript
tag of you Vue file. For example inApp.vue
:
<script lang="ts">
export default {
name: 'app'
}
</script>
Troubleshooting
If your editor is yelling at the line import App from './App'
in main.js
file about not finding the App module, you can add a vue-shim.d.ts
file to your project with the following content:
declare module "*.vue" {
import Vue from 'vue'
export default Vue
}
I'm using VSCode 1.13.1 and not seeing it, but I've seen it before.
TSLint, Prettier... Goddess!
I've recorded a 2 min video on Egghead where I explain how you can set up TSLint with Prettier without any conflicts. Go check it out!
Ok, I can use TypeScript... so now what's next?
At this point, TypeScript could already point you out to some errors you haven't noticed before by using built-in and third-party types and gives you a better dev experience by using type inference, as explained in TypeScript at Slack, an article telling how Slack moved their codebase to TypeScript.
Still, you must add your own types by using interfaces, types, enums, classes and whatever you need. That way you'll add more type coverage that TypeScript will use to apply static typing, assuring type safety.
Ideally, you'd use the TypeScript 2.3 strict
compiler option in your tsconfig.json
because it'll bring you the most type safety. Marius Schulz has a well explained article about this. By TypeScript 2.3, the strict option is a group of 4 options, but in future releases it could add more:
strictNullChecks
noImplicitAny
noImplicitThis
alwaysStrict
However, if you have a medium/large codebase, using strict option will make you spend really a huge effort and time solving all the type shortage.
For that case, a good way to integrate TypeScript is to start with the most flexible configuration, and as you add more type coverage to your codebase, start to enable individually the flags mentioned above, till you get to the point that you can apply the strict
option, so you can approach it in a pragmatic way.
Conclusion
TypeScript brings you type safety to your codebase from the very start, but the more types you define, the more easy to detect bugs and errors and to make the code maintainable. Vue from version 2 is shipped with typings, so we can make use of them. They become more powerful when you use OOP (Object Oriented Programming) in Vue, but will see that in another post.
If you like it, please go and share it! You can follow me on this blog or on twitter as @alexjoverm. Any questions? Shoot!
Originally posted at alexjoverm.github.io on June 28, 2017
Top comments (2)
Thanks for this! Had to do this recently. I followed the readme from Microsoft's TypeScript Vue Starter and I was good to go.
Yes, that's a good example as well, maybe a bit extensive. In this post I wanted to show how to do it using the vue-cli webpack and pwa template, since have much more production ready features and lots of projects are based on them. Also to describe how to do it with projects already done with those templates, in a pragmatic way.
Glad you liked it!