umma.dev

TypeScript: Part One

Here I look into types within TypeScript. What they are, when to use them and how to use them in applications.

What Are Types?

In other programming languages such as Java, you are required to explicitly state the type of data that will be held in a variable/method/object. This is not too dissimilar to TypeScript.

Why Are Types Important?

Types are one of the major benefits of using TypeScript. It creates more resilience within applications; it’s easier to debug which consequently leads to less bugs.

How to Use Types in TypeScript

String

let myUser: string = "User One";

Number

let num: number = 100;
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
let big: bigint = 100n;

Boolean

let isDone: boolean = true;

Any

When a value is of type any, you can access any properties of it. This means calling it like a function, assigning it to a value of any type.

Using any disables all further type checking.

let obj: any = { x: 0 };

obj.example();
obj();
obj.anotherExample = 10;
obj = "test";
const x: number = obj;

Arrays

let list: Array<number> = [1, 2, 3];
let x: [string, number];
x = ["test", 100];

Functions

function greet(name: string) {
  console.log("Hello, " + name + "!");
}

greet("test"); // no error
greet(100); // error
function getNumber(): number {
  return 0;
}

Objects

function printNumbers(num: { x: number; y: number }) {
  console.log("Number x: " + num.x);
  console.log("Number y: " + num.y);
}

printNumbers({ x: 1, y: 2 });

Union

This is a way to combine types.

function printID(id: number | string) {
  console.log("Your ID is: " + id);
}

printID(100);
printID("akdfjakdf");
printID("1293SDFPW2031");
function greeting(x: string[] | string) {
  if (Array.isArray(x)) {
    console.log("Hello, " + x.join(" and"));
  } else {
    console.log("Welcome, " + x);
  }
}
function printID(id: number | string) {
  if (typeof id === "string") {
    console.log(id.toUpperCase());
  } else {
    console.log(id);
  }
}
function getNums(x: number[] | string) {
  return x.slice(0, 3);
}

Aliases

Using the same type more than once.

type Point = {
  x: number;
  y: number;
};

function printCoords(pt: Point) {
  console.log("Coordinate x is " + pt.x);
  console.log("Coordinate y is " + pt.y);
}

printcoords({ x: 1, y: 2 });

Interfaces

interface fullName {
  firstName: string;
  lastName: string;
}

function getFullName(full: fullName) {
  console.log("First name " + full.firstName);
  console.log("Last name" + full.lastName);
}

getFullName({ firstName: "first", lastName: "last" });
interface Animal {
  name: string;
}

interface Bear extends Animal {
  honey: bollean;
}

const bear = getBear();
bear.name;
bear.honey;

Type Assertions

Sometimes you will have informaiton about the value TypeScript shouldn’t know about. For example, document.getElementById, TypeScript only knows this will return some kind of HTMLElement but you may know your page will always have an HTMLCanvasElement with a given ID.

const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;

The above is the same as the below.

const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");
let someValue: unknown = "this is a string"
let strLength: number = (<String>value).length;

TypeScript only allows type assertions which convert to a more specific or less specific version of a type.

You can’t do the following:

const x = "hello" as number;

You can however use two assertions, first set to any and then to the desired type:

const example = expr as any as T;

Literal Types and Interfaces

const req = { url: "https://example.com", method: "GET" as "GET" };
handleRequest(req.url, req.method as "GET");

null and undefined

function doSomething(x: string | null) {
  if (x === null) {
    console.log("x is null");
  } else {
    console.log("Hello, " + x);
  }
}

Writing ! after any expression is effectively a type assertion that the value isn’t null or undefined. It’s important to only use when you know the value can’t be null/undefined.

function doNotDo(x?: number | null) {
  console.log(x!.toFix());
}
let u: undefined = undefined;
let n: null = null;

Optional Properties

A type can be set to be optional by putting ? infront of it.

function names(obj: { first: string; last?: string }) {
  console.log(first + " " + last);
}

names({ first: "user one" });
names({ first: "user two first", last: "user two last" });

Void

Void is almost the opposite of any. The absence of having any type at all. Usually it’s used as the return type of functions that do not return a value.

function warnUser(): void {
  console.log("Warning message here.");
}