-
Book Overview & Buying
-
Table Of Contents
Clean Code with TypeScript
By :
In TypeScript, basic types serve as the building blocks for crafting meaningful data representations. They establish a shared understanding between you, the developer, and the TypeScript compiler, ensuring clarity and precision within your code.
Throughout this section, you will gain insights into the basic types in TypeScript, how to effectively utilize them in your code, and discover practical examples and use cases for each type.
In TypeScript, basic types are used to represent the most fundamental data types in the language. The following are the basic types in TypeScript:
string: Represents a sequence of charactersnumber: Represents a numeric valueboolean: Represents a logical value that can be either true or falsenull: Represents a null valueundefined: Represents an undefined valuesymbol: Represents a unique identifierTo use basic types in TypeScript, you can declare a variable with a specific type. Here are some examples:
let fullName: string = "John Doe";
Practical example/use case: Used to represent text data, such as names, addresses, and messages
let age: number = 30;
Practical example/use case: Used to represent numeric data, such as ages, prices, and quantities
let isStudent: boolean = true;
Practical example/use case: Used to represent logical data, such as whether a user is logged in or not
let nothing: null = null;
Practical example/use case: Used to represent the absence of a value
let something: undefined = undefined;
Practical example/use case: Used to represent a variable that has not been assigned a value
let id: symbol = Symbol("id");
Practical example/use case: Used to represent a unique identifier, such as object keys
We've just listed common basic types in TypeScript. If you choose one of these variables, such as the fullName variable, and attempt to reassign it to a different type that doesn't match the expected type, TypeScript will show an error. For instance, in the following figure, we've tried to reassign the fullName variable to a number on line 4:

Figure 1.4 —The squiggly red line under the fullName variable indicates a TypeScript error
If you look closely at line 3, where the reassignment is happening, you will notice the red line. If you hover on the red line, you will notice what the issue is:
Error: Type 'number' is not assignable to type 'string'.
See the following figure for more clarity:

Figure 1.5 — The error details when you hover over the fullName variable
While this example may appear trivial, the implications become crucial in real-world scenarios. Imagine building a financial application in plain JavaScript where precise data types are essential for mathematical operations. In such scenarios, TypeScript's type checking catches potential type errors early, reducing the risk of bugs, such as unintended arithmetic operations between incompatible types (e.g., a string and a number).
Think of a shopping list, a sequence of items you need to buy. In TypeScript, arrays provide similar functionality, serving as ordered collections of values. Just like your list items, each element within an array can be accessed using its index position.
In the following example, we declare a shoppingList array with a type annotation specifying that it should contain strings. We initialize the array with some initial items – "Apples", "Bananas", and "Milk":
const shoppingList: string[] = ["Apples", "Bananas", "Milk"];
If we attempt to add a number (123) into the shoppingList array using the push method, we get a TypeScript error:
"Argument of type 'number' is not assignable to parameter of type 'string'."
In a previous section (on types and interfaces), we discussed objects and types. As an example, we defined the Person type:
type Person = {
name: string;
age: number;
greet: () => void;
};
Now, let's combine this Person type with an array to create a list of individuals, each represented by an object. For instance, we'll include two people, Alice and Bob:
const persons: Person[] = [
{
name: "Alice",
age: 30,
greet() {
console.log(
`Hello, my name is ${this.name} and I'm ${this.age} years old.`
);
},
},
{
name: "Bob",
age: 25,
greet() {
console.log(
`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
},
},
];
In this example, we're already assembling these building blocks to create more robust and type-safe code. If you were to add a value to the persons array that doesn't conform to the structure defined by the Person type, TypeScript would raise an error.
As demonstrated earlier, we continue to reap the benefits of type inference. For instance, if we attempt to add a new person object to our list, TypeScript provides a helpful hint in our code editor regarding the expected property types. Take a look at the following figure:

Figure 1.9 — Code editor displaying type hints for the expected properties
In the examples we've just seen regarding basic types, we explicitly specified the type of the variable. However, TypeScript's type system can infer types automatically. For instance, if we use the fullName variable again without explicitly specifying its type, TypeScript will still complain if we attempt to reassign the variable to a value of the number type:

Figure 1.6 — TypeScript inferring types, even when they are not explicitly stated
Now that we've explored the basics of TypeScript types, let's delve into more complex types in the next section.