Friday, May 28, 2021

3 Ways to Name Types in Typescript

TypeScript type's system is structural and hence, it allows for the easy creation of types based on the shape of data. These types can be created and used without having a name. For example:

let john: {name: string, age: number} = { 
  name: "John Doe", 
  age: 30
}

Where {name: string, age: number} is the type defined.

But there is a problem with using the type definition this way. If we want to create another person and annotate another variable with the type, we would need to repeat ourselves:

let john: {name: string, age: number} = {
  name: "John Doe", 
  age: 30
}

let jane: {name: string, age: number} = {
   name: "Jane Doe", 
   age: 45
}

This is not dry.


Saturday, May 22, 2021

How to implement sleep function in JavaScript

Most popular mainstream languages have a sleep functionality that allows for the pausing of code execution for a specified amount of time. Not surprising this functionality is often implemented via a function usually named sleep. For example:

// ruby
sleep(time_secs)
// python
import time
time.sleep(time_secs)
// Java
Thread.sleep(time_milli_secs)
// Perl
sleep(time_secs)

JavaScript does not have a similar sleep function, although it has the setTimeout function which can be used to achieve a similar purpose. The only problem is, using setTimeout is not as convenient as one would like. This is due to the fact that setTimeout is an asynchronous function, hence one would have to continue the execution of the code, in the callback passed to it, after the elapsed time.

console.log("Executing code..."); 
setTimeout(() => { 
console.log("continue after pause"); 
}, 3000)

This is not convenient.

A more convenient option would be to have something similar to:

console.log("Executing code..."); 
// sleep for some time
// sleep()
console.log("continue after pause");

Unfortunately, this does not exist natively in JavaScript. But this is not to say we can't implement one!


Thursday, May 20, 2021

Callback, Promise and Async/Await by Example in JavaScript

This post is going to show,  by way of code examples, how to take a callback based API, modify it to use Promises and then use the Async/Await syntax. This post won't go into a detailed explanation of callbacks, promises or the Async/Await syntax. For such a detailed explanation of these concepts please check Asynchronous JavaScript, which is a section of MDN Web Docs, that explains asynchronicity and how callbacks, promises, and the Async/Await syntax helps with working with asynchronous JavaScript.

This post is meant for the developer who has somewhat of an understanding of asynchronicity in JavaScript, but requires a straight to the point code example to serve as a quick syntax reference for how to take a callback based API, update it to use promises and finally use the Async/Await with it.

For demonstration purposes, we are going to use the fs.readFile, which is a callback based API from reading files. We will have a file test.txt that would contain some text, we will then have a file script.js that would open the file, read the contents, and print it to the terminal.

The code will first be implemented using callbacks, it would then be updated to use Promises, and finally, instead of using Promise directly, it will be updated to use Async/Await.

Let's get started.


Sunday, May 09, 2021

ip-num v1.3.2 has been released

ip-num is A TypeScript/JavaScript library for working with ASN, IPv4, and IPv6 numbers. It provides representations of these internet protocol numbers with the ability to perform various IP related operations like parsing, validating etc, on them.

A new version of ip-num, version 1.3.2 is now available.

This release contains one new feature and a bug fix.

Add method to split range into smaller ranges of certain size

In previous versions of ip-num, it was possible to take IP ranges with prefix less than /32 and split them into two. For example:

import {IPv4CidrRange} from "ip-num/IPRange";
import {IPv4Prefix} from "ip-num/Prefix";

let ipv4CidrRange = IPv4CidrRange.fromCidr("192.168.208.0/24");
let splitRanges: Array<IPv4CidrRange> = ipv4CidrRange.split();

// console logs:
// 192.168.208.0/25
// 192.168.208.128/25

splitRanges.forEach(range => console.log(range.toCidrString()))

But what if one needs to take an IP range and instead of just splitting into two, there is the requirement to split into a number of ranges with a specified prefix? Well, that is now possible with the addition of splitInto method:

import {IPv4CidrRange} from "ip-num/IPRange";
import {IPv4Prefix} from "ip-num/Prefix";

let ipv4CidrRange = IPv4CidrRange.fromCidr("192.168.208.0/24");
let splitRanges: Array<IPv4CidrRange> = 
ipv4CidrRange.splitInto(IPv4Prefix.fromNumber(26));

// console logs:
// 192.168.208.0/26
// 192.168.208.64/26
// 192.168.208.128/26
// 192.168.208.192/26

splitRanges.forEach(range => console.log(range.toCidrString()))

RangedSet.isCidrAble() incorrect results

Previous versions of ip-num failed to properly report that a string representing a single IP can be represented in the CIDR notation. This has now been fixed:

import {RangedSet} from "ip-num/IPRange";

let rangedSet= RangedSet.fromRangeString("1.2.3.4-1.2.3.4");

// now returns true
console.log(rangedSet.isCidrAble())

As always, ip-num is just an npm install or npm upgrade away.

Feel free to open an issue to discuss a feature or to report a bug.


Sunday, April 25, 2021

Mapped Types in Typescript

This post will explore Mapped Types, another advanced feature of the Typescript type system. It is part of the Introduction to Advanced Types in TypeScript series.

A useful mental model to have when approaching some of the advanced type system features of Typescript is to view them as a mechanism for constructing other types from existing types. This view is spot on when it comes to mapped types as they are a mechanism that Typescript provides by constructing new types by mapping existing types into new ones.

This post would show how this looks like. It would be as beginner-friendly as possible, but having some knowledge of Generics, Union Types and Literal types in Typescript would be a plus.

To kickstart we take a quick again, at the keyof Operator, as it is essential to the workings of Mapped Types.


Tuesday, April 06, 2021

Conditional Types in Typescript

This post is about conditional types in typescript, which happens to be an interesting and powerful feature of the typescript's type system. It is part of the Introduction to Advance Types in TypeScript series.

Conditional types can be seen as a mechanism that allows us to perform ternary operations on types. 

Normally, ternary operations work with values, for example:

resulting value == true ? value A : value B
let value = 10
const isEven = value % 2 == 0 ? true : false
Conditional types gives us the ability to perform similar operation on types. Where we get a type out of two possibility, depending on the outcome of a check. 


Saturday, April 03, 2021

any, unknown and never types in Typescript

This post will be a quick overview of three interesting types in Typescript: any, unknown, and never with the aim of quickly explaining what they are, and when to use them. It is part of the Introduction to Advance Types in TypeScript series.  

To start with, it is a good mental model to view Types from the perspective of set theory. This idea is fully explored in Union and Intersection Types in TypeScript, but for a quick summary, the idea is simple. When types are created, see it as similar to defining a Set. And what do sets contain? they contain objects. The next thing is to see values as objects that belongs to a set. A value defined to be part of a set, would not be allowed in a different set which it does not belong in or overlap with.