DEV Community

Cover image for Your first Introduction to TypeScript
Eric The Coder
Eric The Coder

Posted on • Originally published at eric-the-coder.com

Your first Introduction to TypeScript

Follow me on Twitter: https://twitter.com/EricTheCoder_

What is Typescript?

TypeScript is a javascript superset

Is TypeScript the same as Javascript?

Yes and No. TypeScript has been created by Microsoft and is built on top of javascript.

In short, it is the same as Javascript but with added features.

Everything you know from Javascript will be useful in TypeScript.

Which one should I learn first?

You definitively learn Javascript first. If you don't know Javascript, you will have a hard time learning and understanding TypeScript.

Why create a new language? Javascript is ok, isn't it?

When people start using JavaScript in complex applications, they quickly realize that JavaScript became hard to work in terms of OOP and difficult to find some bugs.

TypeScript was developed by Microsoft to bridge this gap.

So what exactly TypeScript adds to javascript?

  • Powerful type system
  • Type error checking at development time
  • Better Object-Oriented Programming
  • New features like Interfaces, Generics, etc.
  • Meta-Programming like Decorators
  • Compile to javascript that can run on an older browser
  • Code Auto-completion in the editor
  • And more...

Anything else I should know?

TypeScript does not run in the browser or with node.js like Javascript. To execute, TypeScript needs to be converted/compile to Javascript.

Using TypeScript involves the use of a compiler. For example, if you have a file name app.ts, TypeScript compiler will create the javascript equivalent app.js. That one will be used to run your app.

So that is why we say TypeScript help at development time.

How to install and use TypeScript compiler

You can install TypeScript globally on your dev machine with this command

$ npm install -g typescript
Enter fullscreen mode Exit fullscreen mode

To executer the compiler

$ tsc app.js

// or watch mode
$ tsc app.js -w
Enter fullscreen mode Exit fullscreen mode

In watch mode TypeScript will automatically re-compile your app.ts in app.js on every save.

TypeScript config?

There is a lot of config/setting available for TypeScript. I will not cover those in this introduction article but just want to let you know that TypeScript settings are store in a file called tsconfig.json. You can create this file with

$ tsc --int
Enter fullscreen mode Exit fullscreen mode

TypeScript 101

You will now learn how to use basic TypeScript features

Core Types

One of the most valuable features of TypeScript is the type system. In TypeScript you can assign a type to a variable and TypeScript compiler will throw an error if anywhere in your code that type is not respected.

To understand what type, we will do a TypeScript vs Javascript comparison.

Here a regular Javascript code

function add(num1, num2) {
  return num1 + num2
}

const result1 = add(10, 20).       // 30
const result2 = add("10", "20")  // 1020
Enter fullscreen mode Exit fullscreen mode

In this example, result1 will be 30 and result2 will be 1020

Why result2 is not 30?

Since you supply double quotes, Javascript thinks your parameters are string and so execute the code with that logic without reporting any error.

Now imagine the kind of damage this error could do in an accounting application. Finding that kind of bug in a 100k lines of code web application is very hard, very frustrating, and time-consuming.

TypeScript to the rescue!

Let's use the same code above but in TypeScript

function add(num1: number, num2: number) {
  return num1 + num2
}

const result1 = add(10, 20).       // 30
const result2 = add("10", "20")  // editor/compile error
Enter fullscreen mode Exit fullscreen mode

The only difference is the :number type added after the parameter name

In this exemple, the 'const result2 = add("10", "20")' line will report an error in the code editor and when compiling.

Type inference

When a variable is initialized TypeScript can infer/detect the type of the variable automaticaly

let amount: number = 99.95
// same as
let amount = 99.95 // best practice
Enter fullscreen mode Exit fullscreen mode

Both variables will be of type number. The best practice is to let the TypeScript inference do its job since we set the initial value ourselves. That helps avoids repetitive code.

Note that we only specify the type when the variable is not initialized with a value

let title: string
title = "Hello World"
Enter fullscreen mode Exit fullscreen mode

object Type

TypeScript will also infer the object type automatically

const person = {
    name: 'Mike Taylor',
    age: 45
}
Enter fullscreen mode Exit fullscreen mode

Will result in TypeScript object type

const person: {
  name: string;
  age: number;
} = {
  name: 'Mike Taylor',
  age: 45
}
Enter fullscreen mode Exit fullscreen mode

Array type

The syntax to declare an array is: type

const names: string[] = ['Mike', 'John', 'Paul']
const amounts: number[] = [100, 200, 300]
Enter fullscreen mode Exit fullscreen mode

Tuple type

Use when we need a fixed number of values in an array.

const names: [number, string] = [100, 'Mike']
Enter fullscreen mode Exit fullscreen mode

Emun type

Enum is mainly used to assign names to constants

enum Role { ADMIN, READ_ONLY, AUTHOR }
console.log(Role.ADMIN) // 0
Enter fullscreen mode Exit fullscreen mode

You can also specify the key (key can be any type)

enum Role { ADMIN = 100, READ_ONLY = 200, AUTHOR = 300 }
console.log(Role.ADMIN) // 100
Enter fullscreen mode Exit fullscreen mode

Any type

Use any as a fallback if you really don't know the type.

let title: any
title = 25
title = 'Hello World'
Enter fullscreen mode Exit fullscreen mode

Note that this is not a good practice. Try to avoid it!

union type

A variable can be flexible and be assigned with two type

function combine(item1: (string | number), item2: (string | number)) {
    if (typeof item1 === 'number' && typeof item2 === 'number') {
        console.log(item1 + item2)
    } else {
        console.log(item1.toString() + item2.toString())
    }
}
Enter fullscreen mode Exit fullscreen mode

The syntax for union type is: type2 | type2

Type Alias

We can create a custom type that will act as an alias for example a union type

type Dual = number | string

let title: Dual

title = "Hello"
title = 100
Enter fullscreen mode Exit fullscreen mode

object type alias

type User = { name: string; age: number }
const user1: User { name: 'Mike', age: 25 }

// the syntax is then simplyfy
function loadUser(user: User) {
  ..do something...
}

// instead of
function loadUser(user { name: stringl age: number }) {
  ..do something...
}
Enter fullscreen mode Exit fullscreen mode

Function return type

We can specify the return type of a function

function add(num1: number, num2: number): number {
  return num1 + num2
}
Enter fullscreen mode Exit fullscreen mode

Void return type

When a function don't return any value TypeScript will infer the function to be type 'void'

function displayMessage(): void {
  console.log('Hi there')
}
Enter fullscreen mode Exit fullscreen mode

Function type

The declaring syntax is: (var: type, var: type) ⇒ return type

function add(num1: number, num2: number): number {
    return num1 + num2
  }

let calc: Function

// or more specific
let calc: (num1: number, num2: number) => number
calc = add
console.log(calc(10,20))
Enter fullscreen mode Exit fullscreen mode

Unknown type

Variable of type unknown will not be assignable except if we check the typeof the assignment.

let userInput: unknown
if (typeof userInput === 'string') {
  userName = userInout
}
Enter fullscreen mode Exit fullscreen mode

OOP in TypeScript

class declaration

class Product {
  name: string;
  price: number;

  constructor(name: string, price: number) {
    this.name = name
    this.price = price
  }
}

const product1 = new Product('iPad', 500)
Enter fullscreen mode Exit fullscreen mode

Shorthand properties initialization

class Product {

  constructor(private name: string, private price: number) {

  }
}

const product1 = new Product('iPad', 500)
Enter fullscreen mode Exit fullscreen mode

Access Modifiers (private, public, readonly, protected)

class Product {
  private name: string;
  private price: number;

  constructor(name: string, price: number) {
    this.name = name
    this.price = price
  }

  public displayProduct() {
    console.log(this.name, this.price)
  }
}

const product1 = new Product('iPad', 500)
Enter fullscreen mode Exit fullscreen mode

The public keyword is optional because that's the default modifier if none supply.

p*ublic* mean a variable or function available outside of the class

p*rivate* is for variables or functions not available outside of the class

readonly is to variables private and readonly

Protected is for variables or functions available only inside the class or subclass

Inherits

class Friends extends Person {
}
Enter fullscreen mode Exit fullscreen mode

Getters and Setters

class Friend {
  get name() {

  }

  set name(value: string) {

  }
}
Enter fullscreen mode Exit fullscreen mode

Static properties and methods

class Product {
  static defaultName = 'Product x'
  static display name() {
    console.log(defaultName)
  }
}

Person.display('iPad')
Enter fullscreen mode Exit fullscreen mode

interface

interface IsPerson {
  name: string;
  age: number;
  speak(a: string) {
    console.log(a)
  }
}
Enter fullscreen mode Exit fullscreen mode
const me: IsPerson = {
  name: 'Mike',
  age: 25,
  speak(text: string): void {
    console.log(text)
  }
}
Enter fullscreen mode Exit fullscreen mode
class customer implements IsPerson {
  private name
  private age

  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }

  public speak(text: string): void {
    console.log(text)
  }
}
Enter fullscreen mode Exit fullscreen mode

Generics

When writing programs, one of the most important aspects is to build reusable components. This ensures that the program is flexible as well as scalable in the long term.

Generics offer a way to create reusable components. Generics provide a way to make components work with any data type and not restrict to one data type. So, components can be called or used with a variety of data types.

For example, if we want to create an interface with a data property that can contain a different object type

First create the interface

interface Person<T> {
  name: string;
  age: number;
  data: T;
}
Enter fullscreen mode Exit fullscreen mode

The <T> is a placeholder for the type that will be added by TypeScript at compile time

You can then use the generic interface in your code

const person1: Person<string> = {
  name: 'Mike',
  age: 25,
  data: 'Info about person'
}

// or
const person1: Person<string[]> = {
  name: 'Mike',
  age: 25,
  data: ['Info about person', 'info2']
}
Enter fullscreen mode Exit fullscreen mode

In the above example, the same interface has been used to store string and strings arrays.

Discussion (1)

Collapse
ash_bergs profile image
Ash

Great high-level, but detailed, overview of TypeScript... I keep meaning to pick it up and play with it 🤔

Thanks for the write up!