- JS Projects Utilizing TypeScript
- How to Add TypeScript to a JavaScript Project
- How can I add types to my JavaScript project?
- What is Typescript?
- Hello world in TypeScript
- The «small step for man» approach — Adding TS support for existing applications
- The open for business approach — Adding TS support for existing libraries.
- The skeleton — a step towards the future
- The all in approach — Converting a full codebase from JS into TS
- How to convert a JavaScript application to support TypeScript.
- Install typescript
- Typescript config file
- Create your first .TS file in your project
- Take care of your package.json file
- Conclusion
- JS Projects Utilizing TypeScript
JS Projects Utilizing TypeScript
The type system in TypeScript has different levels of strictness when working with a codebase:
- A type-system based only on inference with JavaScript code
- Incremental typing in JavaScript via JSDoc
- Using // @ts-check in a JavaScript file
- TypeScript code
- TypeScript with strict enabled
Each step represents a move towards a safer type-system, but not every project needs that level of verification.
TypeScript with JavaScript
This is when you use an editor which uses TypeScript to provide tooling like auto-complete, jump to symbol and refactoring tools like rename. The homepage has a list of editors which have TypeScript plugins.
Providing Type Hints in JS via JSDoc
In a .js file, types can often be inferred. When types can’t be inferred, they can be specified using JSDoc syntax.
JSDoc annotations come before a declaration will be used to set the type of that declaration. For example:
You can find the full list of supported JSDoc patterns in JSDoc Supported Types.
The last line of the previous code sample would raise an error in TypeScript, but it doesn’t by default in a JS project. To enable errors in your JavaScript files add: // @ts-check to the first line in your .js files to have TypeScript raise it as an error.
If you have a lot of JavaScript files you want to add errors to then you can switch to using a jsconfig.json . You can skip checking some files by adding a // @ts-nocheck comment to files.
TypeScript may offer you errors which you disagree with, in those cases you can ignore errors on specific lines by adding // @ts-ignore or // @ts-expect-error on the preceding line.
To learn more about how JavaScript is interpreted by TypeScript read How TS Type Checks JS
How to Add TypeScript to a JavaScript Project
dor sever
I love writing code. And I want to be really good at it. But somehow, writing JavaScript has never been my strong suit.
No matter how much I practiced, the same mistakes kept appearing in production: cannot read property <> of undefined exceptions, the famous [Object object] string, and even function calls with an invalid number of parameters.
What’s more, most of the codebases I was working on were really large JavaScript ones. So here is a nice diagram of how it felt to be me:
In this post, I’ll avoid explaining why TypeScript is awesome (and it is), and focus on the tasks you need to complete if you want to migrate your vanilla JavaScript project to a mixed TypeScript project.
By the end of the post, you will be a happier person and will be able to answer the following questions:
- How can I add types to my JavaScript project?
- What is TypeScript?
- How can I use TypeScript in a JavaScript project?
- What are the steps to convert a JavaScript application to support TypeScript?
- How can I take care of build & packaging?
- How can I take care of linting?
- How can I “sell” TypeScript to my organization and developers?
How can I add types to my JavaScript project?
Vanilla JavaScript does not support types at the moment, so we need some sort of abstraction on top of JavaScript in order to do so.
Some common abstractions are using Facebook’s static type-checker called flow and Microsoft’s language called : typescript .
This blog post will examine the usage and addition of TypeScript to your JavaScript project.
What is Typescript?
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
TypeScript consists of a few parts. The first is the TypeScript language — this is a new language which contains all JavaScript features . Check out the specs for more information.
The second is the TypeScript compiler, tsc (the type system engine) which is a compilation engine that builds ts files and yields js files.
Hello world in TypeScript
As an example, these are the steps you need to take to write your first TypeScript application:
- install TypeScript with npm i typescript
- create a folder called example and cd into it (in your terminal)
- create a file called hello.world.ts
- write the following code in it:
The «small step for man» approach — Adding TS support for existing applications
My first suggestion is to create a mixture of the two languages in a single project, and then write all “future” code in TypeScript.
The combination of two languages in a single project sounds pretty awful at first, but it works quite well since TS was built for gradual usage. At first it can be used just as JS with .ts files and weird import lines.
In this strategy, we will be compiling the migrated TypeScript files and just copying the JavaScript files to an output folder.
The huge benefit of this approach is that it allows a gradual learning curve for the development team (and for you) with language and it’s features. It also gives you hands-on experience and insight into its pros and cons.
I highly recommend starting from this step and then iterating on it with your team before moving forward. For a quick “how to do this”, scroll down to The steps to convert a javascript application to support typescript part.
The open for business approach — Adding TS support for existing libraries.
After you have some hands on experience with TS and your development team agrees it’s worth moving forward, I suggest converting your in-house libraries and modules to support TS.
This can be done in two ways:
The first way involves using declaration files. A simple addition of d.ts files helps the TS compiler type-check existing JavaScript code and gives you auto-completion support in your IDE.
This is the «cheapest» option, as it doesn’t require any code changes to the library at all. It also gives you maximum power and types support in your future code.
The second way is to perform a full re-write of TypeScript, which might be time-consuming and error-prone. I would advise against it, unless it proves ROI worthy to your team.
The skeleton — a step towards the future
I assume most developers are «lazy» and usually start their application by copying from a skeleton (which usually contains logging, metrics, configuration, and so on).
This step helps you navigate your way into a bright future, by creating an «official» skeleton for your company. It will be 100% TS, and deprecates the old JS skeleton if one exists.
This typescript-node-starter is a really good first project to start with.
The all in approach — Converting a full codebase from JS into TS
This option requires a total rewrite from JavaScript code to TypeScript.
I would recommend doing this as a final step in the TS migration process since it requires a total application re-write and deep knowledge of TypeScript and it’s features.
You can do such a rewrite (it’s a long process) in the following manner:
- Define clear types for your application business logic, API, & HTTP’s
- Use @types packages for all the libraries in your package.json . Most of the libraries out there support TS, and in this process I suggest migrating them one by one (by just adding @types/ in your package.json file).
- Convert your application logical components in order of their importance. The more unique the business logic, the better.
- Convert the IO parts of your application, database layers, queues and so on.
- Convert your tests.
Keep in mind that there are automated tools designed to ease this process, for example ts-migrate from the Airbnb team.
It tackles this problem from a different perspective, and converts all files to TypeScript. It also allows gradual improvements (like mentioned in the steps above) while the entire codebase is TypeScript from day one.
How to convert a JavaScript application to support TypeScript.
Install typescript
by running : npm install typescript .
Typescript config file
Add a typescript config file, which can be created using the tsc —init command in you CLI.
Here is an example of how our initial config looked:
< "compilerOptions": < "target": "esnext", "module": "commonjs", "allowJs": true, "checkJs": false, "outDir": "dist", "rootDir": ".", "strict": false, "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */ "declaration": true, /* Generates corresponding '.d.ts' file. */ "strictNullChecks": true, "resolveJsonModule": true, "sourceMap": true, "baseUrl": ".", "paths": < "*": [ "*", "src/*", "src/setup/*", "src/logic/*", "src/models/*", "config/*" ] >, >, "exclude": ["node_modules", "dist"], "include": [ "./src", "./test", "./*", "./config" ] >
A few things to notice above:
- We read all the files in the src or test or config directory (using the include flag).
- We accept JavaScript files as inputs (using the allowJs flag).
- We emit all of the output files in build (using the outDirflag ).
Create your first .TS file in your project
I recommend starting by adding a simple TypeScript file (or changing a really simple JS file to a TS one) and deploying. Take this migration one step at a time.
Take care of your package.json file
Here is how our package.json looks before and after:
10. Create a positive buzz in your organization about the change!
I highly recommend tweaking this list according to your team, standards, and time-constraints.
Conclusion
Typescript is super awesome! If you are writing production grade software and the business requirements and availability are high, I strongly encourage you to give typescript a try.
Just remember to take it one step at a time. New languages and frameworks are hard, so take the time to learn and to educate yourself and your team before pushing this process forward.
Create a short feedback loop and value proposition. It’s hard to «sell» a new language to your team and management as it takes time and resources.
So design your migration process with short feedback loops, and try to define clear KPI’s (fewer bugs in production, easier refactoring times, and so on) and make sure the value proposition for your use-case is constantly justified until it becomes the de-facto standard.
Make learning resources readily available. I really enjoyed this talk about TypeScript first steps and this blog post about incremental migration to TypeScript.
Also, don’t miss out on the deno project and the ts-node project. I’m super excited and looking forward to using them soon.
JS Projects Utilizing TypeScript
The type system in TypeScript has different levels of strictness when working with a codebase:
- A type-system based only on inference with JavaScript code
- Incremental typing in JavaScript via JSDoc
- Using // @ts-check in a JavaScript file
- TypeScript code
- TypeScript with strict enabled
Each step represents a move towards a safer type-system, but not every project needs that level of verification.
TypeScript with JavaScript
This is when you use an editor which uses TypeScript to provide tooling like auto-complete, jump to symbol and refactoring tools like rename. The homepage has a list of editors which have TypeScript plugins.
Providing Type Hints in JS via JSDoc
In a .js file, types can often be inferred. When types can’t be inferred, they can be specified using JSDoc syntax.
JSDoc annotations come before a declaration will be used to set the type of that declaration. For example:
You can find the full list of supported JSDoc patterns in JSDoc Supported Types.
The last line of the previous code sample would raise an error in TypeScript, but it doesn’t by default in a JS project. To enable errors in your JavaScript files add: // @ts-check to the first line in your .js files to have TypeScript raise it as an error.
If you have a lot of JavaScript files you want to add errors to then you can switch to using a jsconfig.json . You can skip checking some files by adding a // @ts-nocheck comment to files.
TypeScript may offer you errors which you disagree with, in those cases you can ignore errors on specific lines by adding // @ts-ignore or // @ts-expect-error on the preceding line.
To learn more about how JavaScript is interpreted by TypeScript read How TS Type Checks JS