Basic Types: The Foundation of Type Safety
TypeScript's power lies in its ability to explicitly define what kind of data a variable should hold. While JavaScript has dynamic types, TypeScript provides a robust set of types that cover every scenario in modern programming.
1. Primitive Types
The most fundamental types in TypeScript are the same ones you find in JavaScript, but with strict enforcement.
string: Represents text data. Can use single quotes, double quotes, or backticks (template literals).number: Represents all numeric values (integers and floating-point). TypeScript also supports binary, octal, and hexadecimal literals.boolean: Represents a simpletrueorfalsevalue.bigint: Used for very large integers (ES2020+).symbol: Used to create unique identifiers.
let brand: string = "Nandhoo Learning";
let year: number = 2024;
let isActive: boolean = true;
let bigValue: bigint = 9007199254740991n;
2. Specialized System Types
TypeScript introduces several types that help manage the "logic" of your code.
The unknown Type (Recommended over any)
unknown is the type-safe counterpart of any. You can assign anything to unknown, but you cannot use it until you verify what it is (type narrowing).
let value: unknown = "Hello";
// console.log(value.length); // Error! We don't know if it's a string yet.
if (typeof value === "string") {
console.log(value.length); // OK! Now TypeScript knows it's a string.
}
The any Type (Use with Caution)
Assigning a variable the any type effectively turns off TypeScript for that variable. It is useful for migrating old JavaScript projects, but it should be avoided in professional TypeScript code as it reintroduces runtime bugs.
The void Type
Used primarily as the return type of functions that do not return a value.
function logError(msg: string): void {
console.error(msg);
}
The never Type
Represents values that never occur. For example, a function that always throws an error or has an infinite loop returns never.
function throwFatalError(): never {
throw new Error("System Crash");
}
3. Arrays and Tuples
Arrays
You can define an array of a specific type using either type[] or Array<type>.
let scores: number[] = [10, 20, 30];
let names: Array<string> = ["Alice", "Bob"];
Tuples
A tuple allows you to express an array with a fixed number of elements where the types are known but not necessarily the same.
let person: [string, number];
person = ["Alice", 25]; // OK
// person = [25, "Alice"]; // Error: Types must match the order.
4. Enums: Named Constants
Enums allow you to define a set of named constants, making your code more readable.
Numeric Enums
enum UserRole {
Admin = 1,
Editor, // Automatically 2
Viewer // Automatically 3
}
String Enums
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT"
}
5. Type Inference vs. Type Annotation
In TypeScript, you don't always have to write the type. If you assign a value immediately, TypeScript will infer the type for you.
let message = "Hello"; // TypeScript infers this is a 'string'
// message = 10; // Error! Type 'number' is not assignable to 'string'.
Professional Advice: Use Type Inference for simple variable assignments to keep code clean, and use Type Annotation for function parameters and complex return values.
6. Null and Undefined
By default, null and undefined are subtypes of all other types. However, when you enable the --strictNullChecks flag (highly recommended), you must explicitly allow them using Union Types.
let username: string | null = null;
username = "CoderKid";