Core Concepts of TypeScript
1. Static Typing
- Basic Types:
number
, string
, boolean
, array
, tuple
, enum
, any
, void
, null
, undefined
, never
, object
.
- Custom Types: Use
type
and interface
to define custom types.
- Type Inference: TypeScript automatically infers types but allows explicit declarations to enhance type checking.
let age: number = 30;
let name: string = "John";
let isActive: boolean = true;
2. Interfaces
- Define the shape of an object, including properties and methods.
- Interfaces can extend (
extends
) other interfaces, allowing the construction of complex types.
interface User {
name: string;
age: number;
isActive: boolean;
}
const user: User = { name: "Alice", age: 25, isActive: true };
3. Type Aliases
- Use the
type
keyword to create type aliases, which can define complex types such as union types, intersection types, etc.
type ID = number | string;
let userId: ID = 101;
userId = "A123";
4. Classes
- TypeScript supports ES6 class syntax with added type support.
- Classes can have access modifiers (
public
, private
, protected
) to control access to members.
- Supports abstract classes (
abstract class
) and interface implementation (implements
).
class Person {
private name: string;
constructor(name: string) {
this.name = name;
}
greet() {
return `Hello, ${this.name}`;
}
}
const person = new Person("Jane");
console.log(person.greet()); // "Hello, Jane"
5. Generics
- Generics allow the definition of functions, classes, or interfaces with placeholders for types, promoting code reusability.
- Generics can be constrained (using
extends
) to limit the range of types they accept.
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>("Hello");
6. Modules and Namespaces
- Modules: TypeScript uses ES6 module syntax (
import
, export
) for code organization.
- Namespaces: Used to create a namespace for global variables, functions, or classes to avoid naming conflicts.
// mathUtils.ts
export function add(x: number, y: number): number {
return x + y;
}
// main.ts
import { add } from './mathUtils';
console.log(add(5, 3)); // 8
7. Type Assertions
- Allow you to tell the compiler the exact type of a value using the
as
syntax or angle bracket syntax (<Type>
), helping bypass compiler type checks.
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
- Description: Constructs a type by extracting from
T
all properties that are assignable to U
. This is the opposite of Exclude
.
function isString(value: any): value is string {
return typeof value === "string";
}
function print(value: string | number) {
if (isString(value)) {
console.log("It's a string: " + value);
} else {
console.log("It's a number: " + value);
}
}
9. Union and Intersection Types
- Union Types: Allow a variable to be one of several types, defined using the
|
operator.
- Intersection Types: Combine multiple types into one, defined using the
&
operator.
type SuccessResponse = { success: true, data: string };
type ErrorResponse = { success: false, error: string };
type Response = SuccessResponse | ErrorResponse;
function handleResponse(response: Response) {
if (response.success) {
console.log(response.data);
} else {
console.log(response.error);
}
}
10. Decorators
- Decorators are a special type of declaration that can be attached to a class declaration, method, accessor, property, or parameter, often used in meta-programming like logging or access control.
function ReadOnly(target: any, key: string) {
Object.defineProperty(target, key, {
writable: false
});
}
class Book {
@ReadOnly
title: string = "TypeScript Handbook";
}
const book = new Book();
book.title = "New Title"; // Error: Cannot assign to 'title' because it is a read-only property.
11. Asynchronous Programming
- Supports
async/await
syntax, making asynchronous code appear synchronous.
- Combines
Promise
with async
to handle asynchronous operations.
async function fetchData(url: string): Promise<void> {
try {
let response = await fetch(url);
let data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
fetchData("https://api.example.com/data");
12. Compiler Configuration (tsconfig.json
)
- Configure TypeScript compilation options through the
tsconfig.json
file, including target version (target
), module resolution (module
), strict mode (strict
), path aliases (paths
), etc.
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
13. Strict Mode
- TypeScript provides a strict mode (
strict
), which includes a series of checks and constraints to improve code robustness and safety.
function greet(name: string | null) {
if (name === null) {
throw new Error("Name cannot be null");
}
return "Hello, " + name.toUpperCase();
}
14. Utility Types
- TypeScript includes built-in utility types like
Partial
, Pick
, Omit
, Readonly
, Record
, etc., for manipulating and transforming types.
14.1. Partial<T>
- **Description**: Constructs a type with all properties of `T` set to optional. This is useful when you want to create an object that has only some of the properties of a given type.
interface Todo {
title: string;
description: string;
completed: boolean;
}
type PartialTodo = Partial<Todo>;
const todo: PartialTodo = {
title: "Learn TypeScript",
// description and completed are optional
};
14.2. Pick<T, K>
- **Description**: Constructs a type by picking a set of properties `K` from type `T`. This is useful when you want to create a type with a subset of properties from another type.
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<Todo, "title" | "completed">;
const todo: TodoPreview = {
title: "Learn TypeScript",
completed: false,
// description is not included in TodoPreview
};
14.3. Omit<T, K>
- Description: Constructs a type by omitting a set of properties
K
from type T
. This is the inverse of Pick
, where you remove certain properties from a type.
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Omit<Todo, "description">;
const todo: TodoPreview = {
title: "Learn TypeScript",
completed: false,
// description is omitted
};
14.4. Readonly<T>
- Description: Constructs a type with all properties of
T
set to readonly
, meaning they cannot be reassigned after being set.
interface Todo {
title: string;
description: string;
}
const todo: Readonly<Todo> = {
title: "Learn TypeScript",
description: "Understand the basics of TypeScript",
};
// todo.title
14.5. Record<K, T>
- Description: Constructs a type with a set of properties
K
of type T
. It is often used to define an object with a specific set of keys and a uniform type for the values.
type Page = "home" | "about" | "contact";
type PageInfo = Record<Page, string>;
const nav: PageInfo = {
home: "/home",
about: "/about",
contact: "/contact",
};
14.6. Required<T>
- Description: Constructs a type by making all properties of
T
required. This is the opposite of Partial
.
interface Todo {
title?: string;
description?: string;
}
type RequiredTodo = Required<Todo>;
const todo: RequiredTodo = {
title: "Learn TypeScript",
description: "Understand the basics of TypeScript",
// Now both title and description are required
};
14.7. Exclude<T, U>
- Description: Constructs a type by excluding from
T
all properties that are assignable to U
. This is useful for filtering out types from a union type.
type T = string | number | boolean;
type NonBoolean = Exclude<T, boolean>;
const value: NonBoolean = 42; // Allowed: string | number
// const value: NonBoolean = true; // Error: boolean is excluded
- Description: Constructs a type by extracting from
T
all properties that are assignable to U
. This is the opposite of Exclude
.
type T = string | number | boolean;
type StringOrNumber = Extract<T, string | number>;
const value: StringOrNumber = "hello"; // Allowed: string | number
// const value: StringOrNumber = true; // Error: boolean is not included
14.9. NonNullable<T>
- Description: Constructs a type by excluding
null
and undefined
from T
. This is useful when you want to remove null
and undefined
from a type.
type T = string | number | null | undefined;
type NonNullableT = NonNullable<T>;
const value: NonNullableT = "hello"; // Allowed: string | number
// const value: NonNullableT = null; // Error: null and undefined are excluded
14.10. ReturnType<T>
- Description: Constructs a type consisting of the return type of function
T
.
function getUser() {
return { name: "Alice", age: 25 };
}
type User = ReturnType<typeof getUser>;
const user: User = { name: "Alice", age: 25 };
15. Type Compatibility
- TypeScript uses a structural type system, meaning type compatibility is based on the structure of the types rather than the names.
interface Person {
name: string;
age: number;
}
interface Employee {
name: string;
age: number;
position: string;
}
let person: Person = { name: "John", age: 30 };
let employee: Employee = { name: "Alice", age: 25, position: "Developer" };
person = employee; // Allowed because `Employee` has all properties of `Person`.
---