DEV Community

Fernando Alvarez
Fernando Alvarez

Posted on • Originally published at Medium on

Level Up your VueJS project with Typescript (Part 2): Translating Components to Typescript

If you missed part 1, go to this post:

Level Up your VueJS project with Typescript (Part 1): Installing Typescript

For the completed version of this part, use this branch of the project repo:

jefer590/upgrade-vuejs-ts-series

In part 1, we prepared our project to use Typescript and was only installation + configuration. For many of you that part could be considered the “boring” part and I understand it! To compensate that, in this part we will translate almost all our VueJS Files (Home View+Components) to use Typescript! So let’s begin.

Translating the “Hello.vue” Component — Single File Component

For this component, we are going to replace only the <script> part with TS, the HTML template doesn’t need any modifications (one advantage of using SFC 🙌).

When we open this file we noticed that the file is very simple:

  • The component data is only a variable called text with a string
  • There’s only one computed property called textUpper that uses text

Try to remember this because we are going to delete all the script part of that component and we will rewrite it using TS starting with:

You will noticed that we added a lang="ts". This means that we are telling to Vue Loader the script inside this SFC will be compiled/transpiled using Typescript.

After that, we will use a library that I absolutely love for VueJS TS development called vue-property-decorator that is already included in the project

kaorun343/vue-property-decorator

And using that library, we will start to use this pattern for every component that we will make with TS

Now you may ask, “what does this even mean?” let me explain it quickly:

@Component is using a feature in TS called Decorators and in this context will pass some metadata of the component to the class. The metadata is basically all the properties that are available in the VueJS Component like data , methods , components , mixins , etc…

In export default class Hello Extends Vue we are doing almost the same as the traditional way that is exporting the VueJS component object but we have TWO main differences:

  • The class name will be also the name of the component
  • Since this is Typescript, we need the VueJS object to be inherited to have the types available and also to tell to VueJS that this is a component object.

To declare the textdata or any kind of data in your VueJS component, create simple a class property and initialize it with the “Hello” string:

private text: string = 'string'

this line is pretty much the same as:

and to create the textUpper computed method, we need to create a “getter”inside our component class

which, in the traditional way, translates to:

After that, our “Hello.vue” Component should look like this:

If you run the project with these changes you will notice that everything is working as expected.

Translating the “World.jsx” Component — TSX Component

For this file, the first thing we need to do is rename it to use the .tsx file extension. If you are running the project, the hot reloading will fail because the compiler is not accepting how this file is done. Let’s translate this!

First, copy all the content of the file and put it somewhere else because we are going to totally rewrite the World.tsx file. After you clean the file, we will declare our Component class in the same way as the Hello.vue file:

Let’s do the same as the Hello.vue with the data and computed property!

Since this is a TSX file, a render function will be needed. To type that function, the parameter of h needs to use the Vue.CreateElement Interface and the render function needs to return Vue.VNode which translates to the “HTML” returned in that function:

This is a good amount of code to check if everything is working. After trying, it will appear an error like this:

To fix this, in the Home.vue view, change the import of World.jsx to use TSX instead. After that, the project should run fine with the only problem that our text is not updating. Since this is TSX/JSX we need to attach the events manually. To fix that, we need to add a method to the on-input event of our input and create a class method that changes the value of text to use the passed text.

After this change, the text mutation should work fine!

Translating the “Home.vue” View

The only thing left to update for now is the Home.vue file. Go to the file, copy the component imports and delete the script part. We will follow next the same pattern to create a class component but adding the component imports:

And to attach the Hello and World components, we will use the @Component decorator by passing an object with the components key as if it were a traditional VueJS object:

After save, the project should start to work properly again.

That all for part 2 friends! Stay tuned for part three where we are going to translate the Vuex module to use Typescript and also how to use it inside a Typescript Class Component!

🙌 Thanks for reading! 🙌

Top comments (1)

Collapse
 
flozero profile image
florent giraud

That's interesting to see people add typescript in vue gg for that. Just a point on it in my 2 last projects people ask me to rollback typescript for default vuejs javascript.
Why ? I agree that point for now typescript ca be hard for new devs and i am not sure about the improvement on dev and vuejs comprehension.
Just wanted to point that but gg for your work