DEV Community

loading...

Basics of TypeScript an introduction

Kyle
・6 min read

I was trying to explain TypeScript to my coworkers and I had the idea to write it down so I wrote my first article! This article will just go over the very basics and give a quick overview but isn’t at all a full guide.

What is TypeScript?

Typescript is a superset of JavaScript, meaning it has all the features JavaScript has but it adds some extra features. For instance, TypeScript adds features like optional static typing, classes, and interfaces (apart from static typing these features are mostly supported in newer ECMAscript version as well). TypeScript is, eventually, TypeScript converts to javascript using a transcompiler like TypeScript Checker or Babel.

What are the benefits? Why would you want to use TypeScript?

Essentially if you use TypeScript and types correctly it will result in fewer bugs and a more robust application. But why? because TypeScript:

  • provides error checking at compilation.
  • provides type checking but more about this later.
  • provides better developer tooling support since the compiler informs the IDE about problems in real-time, so the developer is able to spot problems early so you can fix them before runtime.
  • Provides support for new ECMAScript features which are not always supported in all browsers, for instance, classes, the spread operator, and de-structuring.
  • TypeScript helps in properly structuring your code and keeping your codebase consistent.

So what's type checking?

Type checking is assigning “types” to various parts of your TypeScript program like variables, expressions, or functions. A type is a piece of data telling the compiler the intentions of the programmer and it defines what a program should do. For example, if you type a variable with a string type the compiler checks it and verifies that variable stays a string through your entire program. The programmer’s intentions are clear because the variable type won’t change it’s clear what it will become, and what it should do.

Optionally static typing and type inference

JavaScript is a dynamically typed language which means that JavaScript doesn’t know what type a variable, function, expression, etc. is, until it’s “checked” at runtime. This might mean that there is a possibility of bugs creeping in your code because JavaScript falsy assumes that a variable, function, or expression is a certain type but it actually wasn’t so which probably wasn’t the intention of the developer. By using TypeScript correctly these kinds of errors may be a thing of the past.

While typescript is optionally typed it’s still less explicit than JavaScript because of type inference. Type inference basically means that even if you don’t explicitly type your code, TypeScript still tries to type your code “automatically” in the background. While this isn’t perfect, for instance, it will automatically type something as “any” which might lead to unexpected behavior, but it will still save you from a few errors or bugs.

Simple JavaScript example:

// js
let myString = "string"
myString = 24

We are declaring a string and converting it to a number but JS doesn't care if you do this. It might be fine. In some cases, but you can unintentionally change the value of the variable which might break your code.

//ts
let myString: string = "string"
myString = 24

In TypeScript, we type the variable as a string when we convert it to a number, like in the above example, the compiler will give you an error.

drawbacks of using TypeScript:

There are, of course, drawbacks to using TypeScript:

  • There is a learning curve so it might take some time to get used to TypeScript.
  • It’s a bit harder to set up a codebase because, for example, - - you need to set up a compiler.
  • you need to use a compiler which takes some time to compile every time.
  • When using third party libraries there is the need for definition files that aren’t always available.

How to use TypeScript

Commonly used types

Boolean

A simple true/false value

const myBoolean: boolean = true;

Number

A number is a floating-point value. Hexadecimal, decimals, binary and octal literals are also supported.

const decimal: number = 4;
const hex: number = 0xf00d;
const binary: number = 0b11100;
const octal: number = 0o344;

String

A simple textual type.

const myString: string = "I'm a piece of text";

Array

A simple array can be written a few different ways.

// The type of element inside the array is defined followed by the [] array notation.
const list: number[] = [1, 2, 3];
// The generic array type with the element inside the array defined inside the <> brackets.
const list: Array<number> = [1, 2, 3];

Tuple

An array with a fixed number of elements where you know the types of the values, but an element in the array doesn’t have to be the same type.

let tuple: [number, number, string];
// Using it correctly.
x = [4, 10, "hello"];
// Using it incorrectly.
x = [10, "hello", "hello"];

Object

Object, as the name says, is the type for objects or technically speaking Non-Primitive data types. There are two ways of typing objects:

const userObject: object = {name: "name", age: 100};
const userObject: {}  = {name: "name", age: 100};

// a more complex example
const userObject: {[key: string]: name | number} = {name: "name", age: 100};

Any

The types that will allow everything. It’s not necessarily recommended to use any because it defeats the purpose of typing but if you’re stuck or the content is dynamic you could consider using any.

let whatIsThis: any = 4
// Still no error
whatIsThis = false

Undefined and Null

These are self-explanatory a null and undefined type.

const variable1: undefined = undefined;
const variable2: null = null;

Never

The never type is the type of value that never occurs. For instance, a function that never returns anything doesn’t finish running at all for example when a function throws an error.

// The function never gets to the end. 
const error(message: string): never => {
    throw new Error(message);
}

Void

A Void type means that there is no type. Mostly used in return types for functions that don’t explicitly return a value. The difference with never is that avoid function explicitly returns a value because it returns the undefined value. Never just never returns anything it doesn’t even return undefined.

const myConsoleLogFunction(): void =>  {
    console.log("This is my warning message");
}

Typing variables

Like in most above examples typing variables is the most common use case in TypeScript and it’s easy!

// Typing a function 
const myBoolean: boolean = true;

“Chaining” types to have more types for one variable is also possible.

// Typing a function 
let myBooleanOrString: boolean | string = true;
myBooleanOrString = now its a string;

Typing functions / return types for functions

Like we saw before we can actually type parameter and add return types inline. It’s also possible to specify everything with the help of an interface.

// inline typing
const returnString = (myString: string): string => {
  return myString;
}

// types with interfaces
interface ReturnStringFunction {
  (myString: string) => string;
}

const returnString: ReturnStringFunction = myString => {
  return myString;
}

Interfaces

When you need to define more complex data structures, like objects, functions, or classes, you can use interfaces to do so. Basically it’s a “contract” in your application telling TypeScript what’s inside your data structure.

interface User {
    firstName: string;
    lastName: string;
    occupation: string;
    age: number;
}

const registerUser = (registerUser: User) => {
    console.log(registerUser);
}

extending interfaces

To make your code/interfaces more re-usable and consistent you can also extend your interfaces when needed.

interface User {
    firstName: string;
    lastName: string;
    occupation: string;
    age: number;
}

interface UserAndMarketingMail extends User {
  acceptedMarketingMail: boolean;
}

const registerUser = (registerUser: UserAndMarketingMail) => {
    console.log(registerUser);
}

Types

types are similar to interfaces and can be used to type more complex data structures.

type User = {
    firstName: string;
    lastName: string;
    occupation: string;
    age: number;
}

const registerUser = (registerUser: User) => {
    console.log(registerUser);
}

extending type

type User = {
    firstName: string;
    lastName: string;
    occupation: string;
    age: number;
}

type UserAndMarketingMail = User & {
    acceptedMarketingMail: boolean;
}

const registerUser = (registerUser: User) => {
    console.log(registerUser);
}

Interfaces vs types

type interfaces are similar but there are some differences:

  • If you declare an interface with the same name twice Typescript will merge them into one interface. Types don’t behave the same way.
  • interfaces can only be used for object types but a type can be used for primitive data objects like strings, booleans, numbers, etc.
type info = string | { petName: string };
// or
type MyNumber = number;

interface MyNumber extends number {}
// 'number' only refers to a type, but is being used as a value here.

// this is fine!
interface MyNumber extends Number {}
  • type aliases can use computed properties.
type Keys = "petName" | "species"

type PetInformationType = {
  [key in Keys]: string
}

const test: PetInformationType = {
  petName: "jack",
  species: "dog"
}

Generics

To make your code reusable you can use generics. If you look at the code below. without Generics we would have to give the myUser a specific type and if we want to use this function with another type we would have to make a new function with a different type, but generics make your code is much more reusable!

const myUser<T>(user: T): T => {
  return user;
}

// and you can use it like this:
const output = myUser<string>("myString");
// or alternatively let typescript infer the type based on parameter type we pass:
const output = myUser("myString"); 

generic interface

interface GenericIdentityFn<T> {
  (arg: T): T;
}

function identity<T>(arg: T): T {
  return arg;
}

let myIdentity: GenericIdentityFn<number> = identity;

There is much more to TypeScript than this article covers but it should give you a basic overview of what TypeScript is and how it can be used. I hope this article helped you understand TypeScript a little bit better and thank you for reading!

Discussion (0)