TypeScript

TypeScript is a typed, compiled, generic, and enhanced JavaScript.

  • πŸ‘‰ Compiling a .ts generates a .js
  • πŸ‘‰ The compiler (and IDEs) can detect errors/mistakes
  • πŸ‘‰ The code is cleaner (enums...)
  • πŸ‘‰ You can compile into any version of JavaScript

Where to learn?

➑️ Install (don't use -g, be clean)

$ npm install typescript
$ npx tsc --init # create a tsconfig.json

➑️ Compile

$ npx tsc --project tsconfig.json
$ npx tsc --project tsconfig.json -w # auto-compile

➑️ Creating/using a tsconfig.json (doc) is optional.


πŸ”Ž General overview πŸ”Ž

You need to specify the type of every variable, parameter... unless it's implicit, e.g., it can be deduced by the compiler.

Some types

// πŸ‘‰ Basics
let aaa : any = ""; // ❌ bad/too generic
let bbb : number = 0;
let ccc : string = "xxx";
let ddd : boolean = true;
// πŸ‘‰ a variable can have multiple types
let eee : string | undefined | null = undefined;
// πŸ‘‰ Object
let fff : object = {};
let ggg : { x: string } = { x: "xxx" };
let hhh : (v: string) => string = ((v) => v);
let iii : number[] = [5, 10];
let jjj : [string, string] = ["xxx", "yyy"];
// πŸ‘‰ Special
let kkk : Promise<string> = (async () => ("xxx"))();

If you know that something is not null, use !!

// querySelector returns Element | null -> Element
const xxx : Element = document.querySelector("#xxx")!!

You can create aliases for types:

type XXX = Record<string, string>
let xxx : XXX = {};

➑️ See also Classes, Interfaces, and Records.

Functions

Inside a function, instead of x: type | undefined | null, you can use x?: type which is the same.

// πŸ‘‰ A function parameters
function f(list: number[], xxx?: boolean, yyy = false) {}
// πŸ‘‰ A return type
function f() : string | null {}

Disable a warning

You can do it by adding @ts-ignore before any unresolvable warning.

// @ts-ignore
load(xxx); // code generating a warning 

JavaScript syntax

These may have been added in newer versions of JavaScript.

let x = y ?? 0 // if "y" is null/undefined, then x = 0

// cast to a more specific type
let random : any = 5
let fiveNumber : number = <number>random;

// enums
enum Enum { A, C = 2, D } // values are [0, 2, 3]

Export/Import

What was exported, can be imported into another file.

// file.ts
export function xxx() {}
export class YYY {}
export enum ZZZ {}
// xxx.ts
import { xxx, YYY, ZZZ } from "../files/file";

πŸ—ƒοΈ Classes πŸ—ƒοΈ

The syntax is mostly the same as in JavaScript. Modifiers to change the visibility were added: public, private, and protected.

class Example {
    // ➑️ ex: private static constant
    private static SELECT_KEY = 'match_id';

    // ➑️ attributes
    xxx?: boolean // public, nullable
    public yyy: string = ""

    // ➑️ ex: constructor + private attribute
    constructor(private Id: number) {}

    // ➑️ ex: public static function
    public static getString() : string | undefined {
        return this.SELECT_KEY;
    }

    // ➑️ ex: protected function
    protected doXXX() : number {
        return this.Id
    }
}

Interfaces

Interfaces are used to declare a Type.

interface XXX {
  xxx?: boolean
  yyy: {
    title: string,
    url: string
  }
}

Records

Records are objects with dynamic keys.

const x : Record<string, number> = {}
x.five = 5

Getters and setters

There is a new way to write getters/setters.

class Example {
    get number() : number { return 10; };
    set number(n?: number) { /* code */ };
}

// usage
let example : Example = new Example();
example.number; // call "get"
example.number = 5; // call "set"

Inheritance

It's the same syntax as in JavaScript.

class A {}
class B extends A {
    constructor() {
        super()
    }
}

πŸ₯Š Create a TypeScript library πŸ₯Š

If you want to create a library, and use it in another local project, you must at least provide a name and a version inside your package.json.

{
  "name": "xxx-library",
  "version": "0.0.1"
}

You can install it inside another project with:

$ npm i ../path/to/your/local/library

This will create a link to the library inside your project, so you don't need to update the library each time you change something.

You may also update your tsconfig.json to use ESNext

{
  "target": "ESNext",
  "module": "ESNext",
  "moduleResolution": "node",
  // ...
}

πŸ‘» To-do πŸ‘»

Stuff that I found, but never read/used yet.

"module": "ESNext",
"target": "es2021",
"module": "commonjs",
declare module 'xxx' {
  export default function yyy(): ZZZ;
}

/** @type {import('xxx').xxx} */
// ...