Understanding Basic Types in TypeScript

Understanding Basic Types in TypeScript

Typescript 101

Play this article

TypeScript, the superset of JavaScript, has been growing in popularity due to its ability to catch errors during compile-time, improve code readability, and simplify refactoring. With TypeScript's type system, you can enhance the code quality while taking advantage of new features. In this blog post, I’ll dive into the basic types in TypeScript, exploring each one in detail.

The Importance of Types in TypeScript

Types play a significant role in TypeScript, providing type-checking and error-catching at compile-time. By leveraging the power of types, you can catch errors before they even escalate, enhance code readability for team members, and make refactoring a breeze. Let's dive into the basic types in TypeScript and see how they can benefit your projects.

The Basic Types

Let's get started with the fun stuff. TypeScript’s type inference feature automatically determines a variable's data type. However, it's generally a good idea to declare data types when initializing variables.

We assign data types by simply placing a colon after the variable name but before the equal sign:

const {variable name}: {variable type} = {variable value}

This is the convention that most TypeScript data types are declared except for functions and objects.

Some data types come with a bit more complex than that, but you get the general idea. Below are some brief explanations of data types and examples of how to declare them.


The boolean type is used to represent true or false values.

let isActive: boolean = true;


In TypeScript, all numeric values are represented by the number type, including integers and floating-point values.

let age: number = 25;
let weight: number = 68.5;


The string type represents text values.

let name: string = "John Doe";


Arrays are used to store collections of values. TypeScript supports two syntaxes for defining arrays: Type[] or Array<Type>.

let numbers: number[] = [1, 2, 3];
let names: Array<string> = ["Alice", "Bob", "Carol"];


Tuples allow you to create an array with a fixed number of elements of known types.

let person: [string, number] = ["John Doe", 25];


Enums provide a way to create user-defined types with a set of named constants.

enum Color {
let color: Color = Color.Red;


The any type is used when the type is unknown or can change at runtime.

let unknownValue: any = 4;
unknownValue = "A string";
unknownValue = true;


The void type is typically used as a return type for functions that do not return any value.

function logMessage(message: string): void {

Null and Undefined

Both null and undefined have their respective types in TypeScript. They are often used as subtypes of other types.

let empty: null = null;
let notDefined: undefined = undefined;


The never type represents a value that never occurs, typically used for functions that always throw an error or have an infinite loop.

function throwError(message: string): never {
  throw new Error(message);

Type Inference and Type Annotations

TypeScript has a powerful type inference system that tries to deduce the types of variables and function return values based on their usage. It means that often, you don't need to explicitly specify types, as the compiler can infer them for you.

let inferredString = "Hello, World!"; // TypeScript infers the type 'string'
let inferredNumber = 42; // TypeScript infers the type 'number'

However, there are cases when the compiler might not be able to infer the correct type or when you want to be more explicit about the types you're using. In such cases, you can use type annotations to explicitly specify the type of a variable or a function's return value.

let annotatedString: string = "Hello, World!";
let annotatedNumber: number = 42;

function add(a: number, b: number): number {
  return a + b;

Type Aliases and Custom Types

Type aliases provide a way to create custom types by either giving a new name to an existing type or defining a new type using a combination of existing types. This can help improve code readability and maintainability by creating more descriptive types tailored to your application.

Creating a type alias for an existing type

type Age = number;
let personAge: Age = 30;

In this example, we create a type alias Age for the number type, making it more descriptive and specific to our application.

Defining a new type using a combination of existing types

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

let point: Point = {
  x: 5,
  y: 10,

Here, we create a new custom type called Point using an object type with two properties, x and y. This makes it easier to understand the structure of the object and its purpose in our application.

Using union types with type aliases

Type aliases can also be combined with union types, allowing you to create a custom type that can hold different values.

type StringOrNumber = string | number;

let inputValue: StringOrNumber = "TypeScript";
inputValue = 42;

In this example, we create a type alias called StringOrNumber that can hold either a string or a number. This provides flexibility in our application while maintaining type safety

Union and Intersection Types

Union and intersection types play crucial roles in creating complex type definitions, allowing developers to combine types in flexible and powerful ways.

Union types

Union types represent a value that can be of one of several types. It is denoted using the | symbol between the types.

type StringOrNumber = string | number;

function printValue(value: StringOrNumber) {

printValue("Hello, World!");

In this example, the StringOrNumber type is a union type that can be either a string or a number. The printValue function accepts a parameter of this union type, allowing it to handle both strings and numbers.

Intersection types

Intersection types are used to combine multiple types into one, creating a new type that includes all the properties of the original types. It is denoted using the & symbol between the types.

type A = {
  a: string;

type B = {
  b: string;

type C = A & B;

let objectC: C = {
  a: "Hello",
  b: "World",

In this example, the C type is an intersection type that combines the properties of both A and B. The objectC variable must have both a and b properties, as defined by the intersection type.

That's a wrap!!

Understanding and utilizing TypeScript's basic types can have a significant impact on the quality of your code. It helps catch errors during compile time, improves code readability, and simplifies refactoring. As you continue to work with TypeScript, you'll discover even more benefits of this powerful language. I encourage you to explore TypeScript further and apply these concepts to your own projects, creating more robust and maintainable codebases. See you in next one 👋

Did you find this article valuable?

Support Ashutosh Bhadauriya by becoming a sponsor. Any amount is appreciated!