When we talked about TypeScript a little while ago, we concluded by stating that TypeScript is a development tool that helps compile statically-typed code to valid JavaScript. Today, we’ll look to see an example of this.
We’ll begin with an empty project folder called typescript-compile/
.
Oftentimes, we write our TypeScript code in files denoted with the .ts
file extension that then gets compiled to the valid .js
counterpart. With that said, we’ll create an index.ts
file in our project directory.
typescript-compile/
index.ts
We’ll prepare a simple function called arraySquared()
that is to receive an array of numbers and will return a new array where each number in the array is multiplied with itself (i.e. each number in the array is squared).
Though there are a few ways to achieve this, we’ll have our function accept an array input argument and use the JavaScript .map() function to map through each item in an array and multiply that item with itself.
const arraySquared = input => {
return input.map(item => item * item);
};
If we looked to log the result of using the function while passing an input array of [1, 2, 3]
, we’ll get a result of [1, 4, 9]
.
const data = [1, 2, 3];
const arraySquared = input => {
return input.map(item => item * item);
};
console.log(arraySquared(data)); // [1, 4, 9]
We’ll see the result logged to our console if we were to run the following command in our project directory.
typescript-compile $: node index.ts
Though we’ve written our code in a .ts
file extension, everything we’ve written has been normal JavaScript. With that said, we’ll look to add static types to certain areas in our code.
Though TypeScript can infer the type of the data
array, we’ll explicitly annotate its static type as an array of number items. This will look something like the following.
const data: number[] = [1, 2, 3];
// ...
The number[]
annotation states the type of data
is to be an array of number
values.
Next, we can annotate that the arraySquared
method is to be called with a single input argument of type number[]
.
// ...
const arraySquared = (input: number[]) => {
return input.map(item => item * item);
};
// ...
Lastly and though this is inferred as well, we’ll annotate the type of each iterated item in our .map()
function to be of type number. Our index.ts
file will now look like the following.
const data: number[] = [1, 2, 3];
const arraySquared = (input: number[]) => {
return input.map((item: number) => item * item);
};
console.log(arraySquared(data));
If we attempted to run the code in the index.ts
file as we’ve done before, we’ll notice we’re unable to do so.
We’re unable to run the code within the index.ts
file because the file no longer contains just JavaScript code. The index.ts
file contains syntax where we annotate static types which is unrecognizable in normal JavaScript.
We’ll need to compile the TypeScript code we’ve written to valid JavaScript before we attempt to run the function.
To help us compile the TypeScript code in the index.ts
file, we’ll install the typescript
library via npm
as a global package.
npm install -g typescript
With the typescript
library installed globally in our working machine, we’re able to use the TypeScript compiler to compile the TypeScript code. Within our project directory, we can achieve this with the tsc
command followed by the file we’re interested in compiling (index.ts
):
typescript-compile $: tsc index.ts
After running the TypeScript compiler, an index.js
file is produced within our project directory.
typescript-compile/
index.js
index.ts
And will look something like the following:
var data = [1, 2, 3];
var arraySquared = function (input) {
return input.map(function (item) { return item * item; });
};
console.log(arraySquared(data));
The index.js
file is the compiled output of our TypeScript code where all the static types have been stripped away. If we were to run the code in the index.js
file, we’ll get the logged message to the console as we’ve seen before.
Let’s change the type of our data
array to instead be an array of string types and attempt to pass it down to the input of the function we’ve created.
const data: string[] = ["1", "2", "3"];
const arraySquared = (input: number[]) => {
return input.map((item: number) => item * item);
};
console.log(arraySquared(data));
If we attempted to run the TypeScript compiler at this moment in time, the compiler will throw an error.
The compiler outputs an error stating that:
Argument of type 'string[]' is not assignable to parameter of type 'number[]'.
Type 'string' is not assignable to type 'number'.
The compiler also informs us that the error originates in the line where we attempt to run the arraySquared()
function with the data array as the argument passed in.
Despite the error, the compiler still outputs the compiled JavaScript code by default. When modifying the compiler options of a TypeScript project, this can be avoided.
The error we’re seeing makes sense. We’re attempting to pass an array of string
values to an input that statically expects an array of number
values. With TypeScript, we’ve been able to see this error as our code is being compiled to valid JavaScript. This portrays how TypeScript is a language where types are checked during compile-time and not during run-time.
An incredibly useful tool in TypeScript development is the Visual Studio Code editor (VSCode). VSCode includes TypeScript language support out of the box to help display potential TypeScript compiler errors and warnings while code is being written.
That's it for today! I didn't send an email last week due to things being a bit busy on my end. For the next little while, I may send emails on a bi-weekly basis instead of a weekly basis.
Till next time! 🙂
— Hassan (@djirdehh)