DEV Community

Cover image for Moving from JavaScript to TypeScript
Andrew Baisden
Andrew Baisden

Posted on • Updated on

 

Moving from JavaScript to TypeScript

Introduction

I have been a JavaScript developer for many years and I did not really have much intention to go outside of my technical stack. There is a lot of safety in sticking with what you already know and trying to learn too many programming languages can be daunting I told myself.

JavaScript is already pretty time consuming to learn and nobody truly masters it because the API keeps getting updated along with the documentation as the language evolves. There are also a lot of frameworks and libraries to learn.

It was outdated thinking and fortunately I saw the light when I was between jobs looking for work. Companies were looking for polyglot developers which essentially means a person who knows and is able to use several programming languages.

Expand your knowledge

https://res.cloudinary.com/d74fh3kw/image/upload/v1644403025/anime-learning_xnrbaz.webp

That is when I realised that JavaScript was not enough if you really want to stand out then you need to be capable of using different programming languages. So back then I decided to learn TypeScript and Python. Ironically I actually managed to get a job but the company only required me to use JavaScript so unfortunately I forgot most of the TypeScript and Python that I learned because I was just not using it on a daily basis.

All of this happened before I was active on tech Twitter and before I started blogging so I really did not understand the concept of building in public and working on side projects. My justification was that I already had a job so I did not need to do programming on weekends too.

Finding work during the pandemic

https://res.cloudinary.com/d74fh3kw/image/upload/v1644403428/pandemic-job-search_dqomkn.webp

Fast forward to 2021 and everything changed. We were now in our second year of this global pandemic living with Covid. It took me about 6 months to get a decent job offer and I have been working at this company ever since. During this period I have worked on projects that had a Python and Kotlin backend. So I was getting exposed to different languages.

JavaScript is still one of the most popular programming languages in the world and is always going to be in high demand. It came top in the Stackoverflow 2021 Survey whereas TypeScript is ranked number 7. So if JavaScript is so popular and highly sought after around the world why bother learning TypeScript?

Why you should learn TypeScript

https://res.cloudinary.com/d74fh3kw/image/upload/v1644404166/information-is-power_qv8dkq.webp

As good as JavaScript is the language still has many flaws when compared to other modern programming languages. And unfortunately there are a lot of people out there who just straight up don't like JavaScript for various reasons.

TypeScript is basically a modern way to develop JavaScript projects and the language compiles to raw JavaScript so your codebase can still be read by a browser and other developers who might not know TypeScript. Honestly the syntax is JavaScript so even if you are not familiar with TypeScript you can still understand what is happening.

TypeScript aims to solve a lot of the problems that JavaScript has which makes the language a lot closer to other modern programming languages. In my opinion anyone who hates JavaScript is likely to fall in love with TypeScript. Or at the very least find less reasons to complain about it.

JavaScript vs. TypeScript

There are quite a lot of differences between the two I will cover some of them here.

Compilation errors

TypeScript is able to flag errors in compile time during the development process. This is a really good feature because it means that you are less likely to have errors at runtime when your app has been built and is running. JavaScript is only capable of seeing these errors at runtime so you are highly likely to have much slower debugging because you are now doing more unnecessary checking. The better tooling available in TypeScript provides a far better experience when writing code.

Static typing vs Dynamic typing

JavaScript uses dynamic typing whereas TypeScript uses static typing. With dynamic typing you can reassign variables because the data type can change. This is not possible with static typing because the data type is defined meaning that if you try to assign a different data type it will show a compile error. There are pros and cons for each method.

// This is valid JavaScript code
let num = 10;
num = '10';
Enter fullscreen mode Exit fullscreen mode
// You will get the error Type 'string' is not assignable to type 'number'.
let num: number = 10;
num = '10';
Enter fullscreen mode Exit fullscreen mode

Describing your data using an interface

TypeScript can use an interface in the code which pretty much describes the structure of an object in the application. It defines the overall syntax that is required for the object so you can use it for documentation and issue tracking inside of your code editor.

It is worth noting that the TypeScript compiler wont convert the interface syntax to JavaScript. It is only used for type checking also known as "duck typing" or "structural subtyping".

// Describe the shape of objects in your code.
interface Series {
    id: number;
    seriesName: string;
    releaseDate: number;
}

// Use the interface for type checking in your object.
const series: Series = {
    // The id needs to be a number
    id: 1,
    // The series name needs to be a string
    seriesName: 'The Book of Boba Fett',
    // The release data needs to be a number
    releaseDate: 2021,
};

console.log(series);
Enter fullscreen mode Exit fullscreen mode

CommonJS modules vs. ES modules

Node.js uses CommonJS modules by default and anyone who is familiar with it will know about the require syntax. In comparison when you use Node.js with TypeScript you have the option to use either require or import and export statements. Of course there are ways to get it working in native JavaScript too if you do your research.

JavaScript CommonJS modules

const express = require('express');
Enter fullscreen mode Exit fullscreen mode

TypeScript ES modules

import express from 'express';
Enter fullscreen mode Exit fullscreen mode

When using TypeScript you get access to a tsconfig.json file which lets you change lots of settings which include the target. This lets you set the JavaScript language version for outputted JavaScript files. For example they can be ES2015, ES2016, ES2017 etc...

TypeScript Drawbacks

TypeScript is pretty amazing but it does have a few disadvantages that you should be aware of. Firstly TypeScript does not work in the browser so you have to compile your code to JavaScript before you can use it.

Fortunately TypeScript has a compiler so when you have got it setup it will automatically compile your TypeScript files to JavaScript and luckily it is a fast process. So you don't have to worry about having to wait around for minutes for your code to compile the process is usually done in seconds.

Another disadvantage is the fact that you are going to be writing a bit more code especially if you want to have static type checking. I don't really see this as a downside though because you are writing more performant and better code which is going to make it more maintainable.

Something else that you need to know is that you will require some Type Declaration packages alongside some of the normal packages that you use. Type Declaration packages describe built-in objects. Declaration files give you a way to declare types or values so there is no need to provide any sort of implementations for the values.

This is not always going to be the case because some packages already have type definitions but not all of them. It is easier to understand in this Express Node.js example below.

JavaScript Express App

npm i express
Enter fullscreen mode Exit fullscreen mode
const express = require('express');

const app = express();

app.get('/', (req, res) => {
    res.send('Home Route');
});

const port = process.env.PORT || 3000;

app.listen(port, () => console.log(`Server running on port ${port}, http://localhost:${port}`));
Enter fullscreen mode Exit fullscreen mode

TypeScript Express App

npm i express @types/express @types/node
Enter fullscreen mode Exit fullscreen mode
import express, { Response, Request } from 'express';

const app = express();

app.get('/', (req: Request, res: Response) => {
    res.send('Home Route');
});

const port = process.env.PORT || 3000;

app.listen(port, () => console.log(`Server running on port ${port}, http://localhost:${port}`));
Enter fullscreen mode Exit fullscreen mode

TypeScript Support

TypeScript is well supported and if your code editor of choice is Visual Studio Code then TypeScript is treated like a first class citizen because Microsoft developed the code editor and the language.

Pretty much all of the popular JavaScript frameworks support TypeScript too. So that includes React, Angular, Vue and Svelte. The framework express.js also has compatibility with TypeScript as do other Node.js frameworks. So there really is nothing stopping you from using TypeScript on the front-end and back-end of your application.

Another advantage is the fact that you can now use ES modules on the back-end and front-end natively. So if you are creating an app with a Node back-end and a React front-end for example. You can now use import and export statements for both and you don't need to use CommonJS modules require statements anymore.

How to learn TypeScript

I learned TypeScript from Scrimba and I also followed another good TypeScript course on Udemy. If you already know JavaScript then it won't take you long to get up to speed with TypeScript. Also if you are new to JavaScript or still learning the basics then it is better for you to wait until you have more experience with it before learning TypeScript.

Learn Typescript for free
Understanding TypeScript - 2022 Edition

Top comments (37)

Collapse
 
lukeshiru profile image
Luke Shiru

Adding to the article, you don't have to type everything. My general tip when working with TS is "only type when it isn't inferred". The first example in the article, types num as number, but that isn't needed. Once you assign a number to it, the type of num is inferred. You can see it working here.

Same applies to the express example, because you installed @types/express, the types for req and res are inferred, so you don't need to import them. You can see that here.

Cheers!

Collapse
 
dvddpl profile image
Davide de Paolis • Edited

I'd also like to stress this point.

Typescript is great but it's also a pain.

More stuff to write, more stuff to read, less flexibility, more complexity in compiling and running tests etc. overall more clutter and things that distract you from your main goal: write code to solve problems.

Use it wisely and when it makes sense.

Let it use inference, tell it to shut up (be it wit ts ignore or with any) when you are prototyping or jotting some poc implementations and so on.

Basically use type and interfaces when it helps making explicit the contracts/signature of methods and object talking to each others.
And don't create mega types or interfaces, use composition. Extend interfaces and use union types/type concatenation.

Collapse
 
lukeshiru profile image
Luke Shiru • Edited

I don't really recommend any or ts-ignore because we have better tools for both. In the case of any:

  • Are you working with something you don't know the type? Use unknown instead.
  • You known it's an array, but you don't know the type of its items? Use unknown[] or Array<unknown>.
  • You know is an object but you don't know the type of its properties? Use Record<PropertyKey, unknown>. Unknown is way better because you can use it when you don't know the type of something, but it doesn't let you access methods inside of it when they might not exist (maybe is undefined or null), first you need to check the type with tools like typeof, or use type casting. Basically is flexible, but without turning into a footgun (a gun you use to shoot yourself in the foot). In the case of ts-ignore there is a better alternative too, which is ts-expect-error. It is similar because it ignores the error in a line, but is better because you can add a comment explaining why you did it, and when you solve the error, TS will suggest to get rid of that comment that is no longer needed:
let value = 42;
// @ts-expect-error Will set type to value later
value = "Life, the Universe and Everything"
Enter fullscreen mode Exit fullscreen mode

Once you "fix it" TS will tell you to remove the comment:

let value: number | string = 42;
// @ts-expect-error Will set type to value later
value = "Life, the Universe and Everything"
Enter fullscreen mode Exit fullscreen mode

Cheers!

Thread Thread
 
dvddpl profile image
Davide de Paolis

I dont recommend it either. not when code is shipped ( or simply being merged to main). I am talking about first phases of coding a specific feature. I want to focus on achieving the functionality.
when it works, i can make it safer, nices, extendable, readable, add all types and error handling etc.

at the beginning i dont want to wast time on defining the types on props or method i will likely refactor and throw away anyway. so having to type Record<PropertyKey, unknown> as result of a method i am jotting down, instead of simply.. not writing anything - is a huge waste of time.
focus on the problem, on the solution, on the code, and just TS-just-shut-the-f*-up and any everywhere!!! you will add types afterwards

having said that - thank your for mentioning @ts-expect-error, i wasnt aware of that and it is definetely very useful.

Thread Thread
 
lukeshiru profile image
Luke Shiru • Edited

so having to type Record as result of a method i am jotting down, instead of simply.. not writing anything

I wasn't suggesting you have to do that, besides generally the return type is inferred correctly in TS, so you might not need to do that ever. Generally know when something will receive an object, you don't have to type every property at first, but using Record< PropertyKey, unknown> is quite useful to get type checking when needed. Besides if that's too tedious, you can always have an aliases like:

type UnknownObject = Record<PropertyKey, unknown>;
type UnknownArray = Array<unknown>;
Enter fullscreen mode Exit fullscreen mode

And then when you're "prototyping" methods or functions, you can just say: "ok, this function takes an object and then it returns its entries" ... and write something simple like:

const objectEntries = (value: UnknownObject) => Object.entries(value);
Enter fullscreen mode Exit fullscreen mode

Which is way safer than doing the same with any ... not to mention that any is the default, so if you'll write a type, why make it any when you can use something more useful? any doesn't actually map to that "mock" phase of coding, because you generally have an idea of what you want to receive, and what you want to do with it. When is a simple type is quite easy to type, just number, or string or whatever ... when is something more complex like an array or an object, that's where unkown becomes useful, because you reall "don't know" what the shape of the thing will be yet.

My point is mainly that you don't think: "This function will take anything, and then....", generally is more like "this function will take a number and ...." or "this function will take an object with some props, idk how those props will look like yet, and then ...". In short any is a bad type because is a "bad abstraction", we don't think "any", we might think "unknown" first and then go from there.

Either way I'm happy that at least the types are added afterwards, and even more happy that my comment was slightly useful for you with that @ts-expect-error. Is not as known as @ts-ignore sadly, but is way more useful.

Thread Thread
 
dvddpl profile image
Davide de Paolis

any doesn't actually map to that "mock" phase of coding, because you generally have an idea of what you want to receive, and what you want to do with it.

Well, often in the first phases of coding I really don't know what i am doing :sweatsmile - and most of all I don't care - I'd love to have a type whatever

Think of TDD, I am working on a feature, i start with an empty method, and have the test fail. maybe i didnt define yet precisely what will the input or output be, then gradually I add some logic and get a clearer picture - and decide that the method is too big, does to much, or the payload should be parsed, filtered, manipulated elsewhere before we pass it to the method.

having to think at types in that phase is to me very distracting.
and having to scatter around Number, Unknown or Promise<unknown[]> is a waste of time (both in writing and reading).

but i agree that is just a short phase, afterwards, i see, appreciate and use all the benefits of typescript and gradually add types ( although I try to minimize it, using lots of inference and eventually using some UnionTypes).
so I am definetly not against TS, but against a premature and eccessive use. like for design patterns and abstraction.

And again thanks for all the little hints (unknown, @ts-expect-error and Partial - that you mentioned on one of your posts, are very clever and useful and i did not know or remember them)

Collapse
 
kostyatretyak profile image
ΠšΠΎΡΡ‚Ρ ВрСтяк

Typescript... overall more clutter and things that distract you from your main goal: write code to solve problems.

This can only be said by someone who doesn't actually use TypeScript. Although I agree that code in TypeScript is often much harder to read.

Thread Thread
 
dvddpl profile image
Davide de Paolis

We use typescript in some of our projects. so this opnionated statement comes from direct experience.
I am not denying that TS is useful, I am stating that it makes code too verbose - and long.

We as devs, have to find a balance between the clarity that comes from typization and the readability of the code itself. When i read code quickly to do a review, or to debug something, i want to be able to quickly read and grasp the underlying logic - TS is too me, too often, simply longer to read.

Thread Thread
 
lukeshiru profile image
Luke Shiru

The thing is, if you do TS correctly, you don't type that much, you generally just type something when that something can't be inferred. For example this is perfectly valid TS:

const add = (a = 0, b = 0) => a + b;
Enter fullscreen mode Exit fullscreen mode

You don't need to do this at all:

const add = (a: number = 0, b: number = 0): number => a + b;
Enter fullscreen mode Exit fullscreen mode

All that is inferred ... so you only type when the compiler can't infer the type, which usually also means that you as a developer reading that might need that type to understand what the function is taking or what is returning. Is almost like just adding comments when the code is actually hard to follow.

Thread Thread
 
dvddpl profile image
Davide de Paolis

Agree. This is what I mean. We don't have to explicitly type everything. Most of the time devs do that though, making the code less readable. (of course that is a problem of how ts is used rather than of ts itself).
What I find annoying is just when you are passing around objects and starting out with my implementation and ts can't really infere much yet and start nagging about missing or invalid props. Then instead of going on with the implementation, you have to fix typing issues..

Collapse
 
maciekgrzybek profile image
Maciek Grzybek

Once you get into Typescript, there is no way back :) I feel like writing anything bigger than a blog in pure JS is just painful :)

Collapse
 
karlkras profile image
Karl Krasnowsky • Edited

"In my opinion anyone who hates JavaScript is likely to fall in love with TypeScript. Or at the very least find less reasons to complain about it."

Agreed, I fell into this group, but I was coming from a Java/.Net background. On the flip side, those who love JavaScript could be put off by imposing what essentially is an OOP layer on top of what has historically been a dynamic language so us "real" developers will be more comfortable with it (which of course I am).

Collapse
 
jwp profile image
John Peters

One day, TypeScript will overtake Javascript. Or get close. There's too much good in it to ignore. It's a wonderful language for Java and C# people.

Collapse
 
j3lte profile image
Jelte Lagendijk • Edited

To be honest, ever since I started writing things in Typescript (I had to learn React for work), it is hard to go back to Javascript. Sure, from time to time I'll write a little bit if absolutely needed, but I will always go back to TS.

I'm a stickler for clean code, Typescript + Prettier + TSLint + VSCode is my preferred way to go.

I type everything, there is hardly an 'any' anywhere in my code. Makes it way easier to debug, write clean code that's understandable...

Lately dabbling with Deno, which is also written in Typescript. Absolutely love it 😊

Collapse
 
bernardbaker profile image
Bernard Baker

I think that this a great article and it's really informative. While some values are inferred, for the purposes of demonstration the snippets are valid examples.

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
andrewbaisden profile image
Andrew Baisden

Sure no problem glad I could help. Those are both great courses and the Scrimba one is free so thats a real bonus. The Udemy course goes in depth though and includes the MERN stack.

Collapse
 
neoprint3d profile image
Drew Ronsman

I will have to learn about typescript

Collapse
 
timbogdanov profile image
Tim Bogdanov

This is a very good introduction to typescript, thank you!

Collapse
 
ingosteinke profile image
Ingo Steinke

How do you manage to build express apps using TypeScript everywhere?
Your example is quite straightforward, but once you add node + express + mongoose it starts getting harder. Most tutorial and StackOverflow code is only JS (mostly JS that does not even pass the recommended ESLint rules either, not to talk about TypeScript yet) and if there are no prebuilt type files, you can end up spending hours guessing what return type a certain function might expect. At least I did when I started a new MERN side project and tried to use TypeScript everywhere. got me so frustrated I'd rather go back to PHP or any other properly typed language for the backend, or maybe use deno next time. What do you think?

Collapse
 
andrewbaisden profile image
Andrew Baisden

Yes this article was just an introduction. I am working on a follow up article Creating MERN Stack Applications 2022 and that tutorial will be using TypeScript. I taught myself how to build a MERN application using TypeScript without too many problems so it can be done.

Deno is a potential option too but I have not used it in a long time.

Collapse
 
lukeshiru profile image
Luke Shiru

Almost every popular framework and library out there already provides its own types, or you just need to install @types/package-name. NPM's website shows a TS icon next to the name if the package already includes types, or a DT icon if you need to install @types/package-name. So for express you need to install @types/express and mongoose already includes its own types. You don't have to type anything manually, generally you can just import things from those libraries and frameworks and use them directly and you'll get great autocompletion and type checking (even if you are in JS instead of TS, you get this benefits).

Collapse
 
j3lte profile image
Jelte Lagendijk

Neat! I knew about the TS icon, didn't know about DT... Thanks for the tip :)

Collapse
 
mycarrysun profile image
Mike Harrison

I'd just like to stress the importance of actually learning the way things work instead of following and relying on tutorials for everything. If you can get good at reading the official documentation for languages/libraries you will be much better off. You'll then be able to use whatever stack you want and understand how they interplay together.

Collapse
 
mrdanishsaleem profile image
Danish Saleem

Thanks for sharing. Saving it for future

Collapse
 
femil profile image
Femil Savaliya

Awesome 😎

Collapse
 
codewithtee profile image
Tabassum Khanum

Andrew Thank you for sharing this! Nice introduction to Typescript.

Collapse
 
andrewbaisden profile image
Andrew Baisden

Thanks for the kind words yes it is. If you already know JavaScript then learning TypeScript will come easy for you.

Collapse
 
pengeszikra profile image
Peter Vivo • Edited

You right: for learning TS best over solid JS knowledge.

Typescript great help over JS started when your program use complex, even dynamic types. Best thing is: you can declare by code any custom types, without irrelevant documentation.

Side note: VS Code isn't able to show complex type to unfolded format, but sometimes that will be handy.

Collapse
 
ronaldaug profile image
ronaldaug • Edited

Typescript does not work in the browser

With a library like roll-up or vite, it's quite easy to make it works in the browser. You can change ".js" extension with ".ts" too.
Check it here