DEV Community

Vivek Alhat
Vivek Alhat

Posted on • Edited on

Type Up Your Game: A Beginner's Guide to TypeScript

Introduction to TypeScript

TypeScript is a strongly typed programming language that builds on JavaScript, adding optional static typing to catch errors at compile-time instead of runtime. This makes your code more robust and easier to maintain.

TypeScript is a programming language that adds optional static typing to JavaScript. This means that you can specify the types of variables, objects, function parameters, and function return values in your code. With TypeScript, you can catch type-related errors at compile-time instead of waiting until runtime.

JavaScript meme

For example, let's say you have a function that takes in two arguments, x and y, and returns their sum:

function add(x, y) {
  return x + y
}
Enter fullscreen mode Exit fullscreen mode

In JavaScript, this function would work fine if you pass in two numbers as arguments. However, if you accidentally pass in a string or another non-numeric value, you would get unexpected results or even errors at runtime.

With TypeScript, you can add type annotations to the function parameters and return value to ensure that they are always numbers:

function add(x: number, y: number): number {
  return x + y
}
Enter fullscreen mode Exit fullscreen mode

Now, if you try to pass in a non-numeric value, you would get a compile-time error, preventing any runtime errors from occurring.

This is just one example of how TypeScript can help catch errors at compile time and make your code more robust and maintainable.

If you know JavaScript, learning TypeScript should be easy.

To configure TypeScript environment, click here.

Type System

Type System allows developers to specify the type of a variable or function parameter. TypeScript includes different types, such as any, void, never, unknown, that can be used to define the type of a variable or function parameter.

TypeScript has the following types:

  1. Primitive Types
    1. String
    2. Number
    3. Boolean
    4. Null
    5. Undefined
    6. Void
    7. Never
  2. Object Types
    1. Array
    2. Function
    3. Object
  3. Special Types
    1. Any

Type Annotation

Type annotation in TypeScript is a feature that allows developers to specify the type of a variable, function parameter, or function return value. This is done by adding a colon (:) followed by the desired type after the variable or parameter name.

To put it plainly, type annotations in TypeScript are a way to indicate the type of value that a variable will hold. We do this by explicitly stating the type of a variable, which is called an annotation.

Let’s look at some examples of type annotation.

Variable

const color: string = 'Purple'
const age: number = 25
const isLucky: boolean = true

const nothingMuch: undefined = undefined
const nothing: null = null
Enter fullscreen mode Exit fullscreen mode

In the code snippet above, you will find different examples of type annotations for variables. By explicitly stating a type using the : syntax, TypeScript guarantees that the variable will only store a value of the specified type.

Array

Array annotation in TypeScript is a feature that allows developers to specify the type of an array and its elements. To annotate an array in TypeScript, you can use the syntax type[], where type is the type of the array elements. For example, to create an array of strings in TypeScript, you can use the following syntax:

const colors: string[] = ['red', 'green', 'blue']
Enter fullscreen mode Exit fullscreen mode

In this example, colors is an array of strings. You can also create arrays of other types, such as numbers or booleans, by changing the type after the :. For example:

const evens: number[] = [2, 4, 6, 8, 10]
const isLucky: boolean[] = [true, false, false, true]
Enter fullscreen mode Exit fullscreen mode

Function

Function annotation allows developers to specify the type of parameters a function will receive and the type of value a function will return. For example, to create a function that will accept two numbers and return their sum, you can use the following syntax:

const add = (a: number, b: number): number => a + b
Enter fullscreen mode Exit fullscreen mode
function add(a: number, b: number): number {
  return a + b
}
Enter fullscreen mode Exit fullscreen mode

If a function does not return anything then you can mention void as a return type. Technically, you can return undefined from a void function.

In some rare cases, a function may never terminate and reach its end. This might happen when a function throws some exception. For example,

const throwSomeException = (message: string): never => {
  throw new Error(message)
  console.log(message)
}
Enter fullscreen mode Exit fullscreen mode

In the above example, the function will never reach its end because it will exit after throwing an exception hence will never return anything. TypeScript has a never type that can be useful in such scenarios.

Object

Object annotation allows a developer to specify types for different object properties and methods.

const person = {
  name: 'John',
  age: 20,
}
Enter fullscreen mode Exit fullscreen mode

The person object in the above code snippet has two properties. The name property stores the name of a person and age property stores the age of a person.

In JavaScript, you can assign a string value to an age property like this,

person.age = '20'
Enter fullscreen mode Exit fullscreen mode

The above code snippet will assign a '20' string value to the age property hence changing the type of data stored in the property from a number to a string. These types of cases might create bugs in your code. To prevent this, you can add types to objects.

const person: { name: string; age: number } = {
  name: 'John',
  age: 20,
}
Enter fullscreen mode Exit fullscreen mode

The above code will ensure that the name variable will only refer to string type values and the age variable will only refer to number type values. If you try to assign any different types then TypeScript will throw an error.

The TypeScript object notation syntax can be improved using Type or Interface notation.

interface IPerson {
  name: string
  age: number
}

const person: IPerson = {
  name: 'John',
  age: 20,
}
Enter fullscreen mode Exit fullscreen mode

As you can see in the above code snippet, you can create an interface for object type and use it for annotation to improve readability. The interface only contains a declaration of object properties and methods.

Type Inference

In type annotation, you have to explicitly specify types for a variable, function, or object. In some cases, it is not necessary to annotate types as TypeScript is smart enough to guess the type from the value. This is called Type Inference.

In Type Inference, TypeScript tries to guess the type of a variable from the specified value.

Type inference only works in the following scenarios:

  1. When variables are initialized.
  2. When default values are set for parameters.
  3. Function return types are determined.

If variable declaration and initialization are done on the same line, TypeScript infers the type of a value automatically without giving annotation.

If initialization is done after declaration then TypeScript inference does not work. It infers type as any.

let someNumber = 3
Enter fullscreen mode Exit fullscreen mode

In the above example, variable someNumber is initialized to value 3 hence TypeScript will automatically infer the type as a number without you specifying the type annotation.

let someNumber // Infers as any
someNumber = 3
Enter fullscreen mode Exit fullscreen mode

It also works in the case of functions.

const add = (a: number, b: number) => a + b
Enter fullscreen mode Exit fullscreen mode

In the above example, since type annotation for parameters is specified there is no need to specify the function return type as TypeScript will automatically infer the return type to a number.

Even though, TypeScript is smart enough to infer function return type. It is always good to annotate the function’s return type. Let’s see this with the help of an example.

function subtract(a: number, b: number) {
  a - b
}
Enter fullscreen mode Exit fullscreen mode

In the above example, the subtract function is not returning anything hence the return type is inferred as void , but the function is expected to return a value of type number. If you add a number as a return type to the above function then TypeScript will throw an error. In this way, you can avoid any runtime bugs in your code using TypeScript.

function subtract(a: number, b: number): number {
  a - b
}
Enter fullscreen mode Exit fullscreen mode

When to use it?

Type Annotation Type Inference
Use it when a variable is declared first and initialized later. Use it always and wherever possible.
Use it when the return type is inferred as any and a specific type needs to be returned.
Use when TypeScript cannot infer the correct type.

TL;DR

  1. TypeScript is a superset of JavaScript that allows to catch errors during development or compile time rather than waiting till run time.
  2. TypeScript’s type system provides primitive types like string, number, boolean, void ,etc., and object types like functions, array, object ,etc.
  3. In type annotation, you have to specify types of a variable, function parameters, or object.
  4. In type inference, TypeScript tries to guess the type of a variable.

Top comments (2)

Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

However, if you accidentally pass in a string or another non-numeric value, you would get unexpected results or even errors at runtime.

a) How do you 'accidentally' pass anything in? YOU are in control of the program and its inputs. It just does what you tell it to.

b) The results should not be unexpected, as JS behaves in a predictable way. They're only unexpected if you do not understand JS

Collapse
 
vivekalhat profile image
Vivek Alhat

Thank you Jon for your comment. I agree that the programmer has control over the program and its inputs. However, mistakes can happen, leading to invalid inputs.

For instance, in the add function in JavaScript, a user may mistakenly input non-numeric data or just mess with the form input and type anything, resulting in runtime errors or incorrect outputs. This issue can be avoided by implementing proper validation checks as well but I wanted to mention this example in the context of TypeScript.

Thank you again for your input.