TypeScript is an open-source programming language developed and maintained by Microsoft. It is a superset of JavaScript that adds optional static typing and other features to help developers build large-scale applications.
let variable1: any;
variable1 = 10; // No type checking
variable1 = "Hello"; // No type checking
// Example for 'unknown'
let variable2: unknown;
variable2 = 10; // Type error: Type 'number' is not assignable to type 'unknown'
variable2 = "Hello"; // Type error: Type 'string' is not assignable to type 'unknown'
// Type assertion is required to assign 'unknown' to another type
let variable3: string = variable2 as string;
TypeScript offers features like static typing, interfaces, classes, modules, generics, and more. These features enhance code maintainability, scalability, and developer productivity.
TypeScript provides static type checking, which helps catch errors during development rather than at runtime. It also offers better tooling support, enhanced code readability, and improved maintainability for large codebases.
TypeScript can be installed via npm (Node Package Manager) using the command 'npm install -g typescript'.
Static typing in TypeScript enables developers to specify types for variables, function parameters, return types, and more. This helps detect type-related errors during development and improves code quality.
Interfaces in TypeScript define the structure of objects by specifying the properties and their types. They enable type checking for complex data structures and facilitate better code documentation and design.
'any' is a type that allows any value to be assigned to it, while 'unknown' is a safer alternative that requires type assertion or type narrowing before using the value.
'strict' mode in TypeScript enables a set of strict type-checking options, including 'strictNullChecks', 'strictFunctionTypes', 'strictBindCallApply', and 'strictPropertyInitialization', ensuring more robust and error-free code.
The 'never' type represents values that never occur. It is typically used to denote functions that never return or variables that cannot have a value.
Decorators are a TypeScript feature used to modify classes, methods, or properties at design time. They enable the addition of metadata and behavior to classes and their members.
TypeScript supports asynchronous programming using features like Promises, async/await syntax, and callback functions. These mechanisms help manage asynchronous tasks effectively.
Generics in TypeScript enable the creation of reusable components that can work with a variety of data types. They allow functions, classes, and interfaces to be parameterized by type.
The 'readonly' keyword in TypeScript is used to indicate that a property can only be assigned a value once, either in the declaration or in a constructor. It ensures immutability for object properties.
'namespace' in TypeScript is a way to organize code into logical groups. It helps prevent naming conflicts and provides encapsulation for related functionalities.
TypeScript fully supports ES6 (ECMAScript 2015) features such as arrow functions, classes, modules, template literals, destructuring, and more. It also adds additional type annotations for better type safety.
Type assertion in TypeScript is a way to tell the compiler about the type of a variable when its type is not known. It is used to access the properties and methods of a variable with a specific type.
// Type assertion using angle-bracket syntax
let someValue: any = "this is a string";
let strLength1: number = (<string>someValue).length;
// Type assertion using 'as' keyword
let strLength2: number = (someValue as string).length;
'keyof' in TypeScript is a mapped type operator that produces a union of string literals representing the keys of an object type. It is often used in conjunction with indexed access types to create type-safe property access.
TypeScript provides options like strict null checks and optional chaining to handle null and undefined values safely. Additionally, union types and type guards can be used to handle these values explicitly.
Type guards in TypeScript are techniques used to narrow down the type of a variable within a certain code block. They include typeof checks, instanceof checks, custom type predicates, and discriminated unions.
Mixins in TypeScript are a way to extend the functionality of a class by combining multiple classes or objects into one. They facilitate code reuse and composition by allowing the incorporation of behavior from different sources.
TypeScript supports inheritance through classes, allowing child classes to inherit properties and methods from parent classes. It also supports method overriding and access modifiers like public, private, and protected.
'null' and 'undefined' are both values representing the absence of a meaningful value. However, 'null' is explicitly assigned by developers, while 'undefined' typically indicates an uninitialized variable or an absence of a value.
let variable1: null = null;
let variable2: undefined = undefined;
// Type error: Cannot assign 'null' to 'undefined'
// variable2 = variable1;
// Type error: Cannot assign 'undefined' to 'null'
// variable1 = variable2;
TypeScript code can be compiled to JavaScript using the 'tsc' (TypeScript Compiler) command-line tool or by integrating TypeScript into build tools like Webpack or Gulp.
The 'as' keyword in TypeScript is used for type assertions, allowing developers to explicitly specify the type of a variable. It is typically used in scenarios where the compiler cannot infer the type automatically.
Variables in TypeScript can be declared using 'var', 'let', or 'const' keywords. 'var' declares variables with function-scoping, 'let' with block-scoping, and 'const' declares constants.
The 'in' operator in TypeScript is used to check if a property exists in an object. It returns 'true' if the property exists, 'false' otherwise.
interface MyInterface {
prop1: number;
prop2: string;
}
let obj: MyInterface = { prop1: 123, prop2: "hello" };
if ("prop1" in obj) {
console.log("Property 'prop1' exists in obj");
}
if ("prop3" in obj) {
console.log("Property 'prop3' exists in obj");
} else {
console.log("Property 'prop3' does not exist in obj");
}
Modules in TypeScript can be created using the 'export' keyword to export functions, classes, or variables from a file, and the 'import' keyword to import them into other files. This facilitates code organization and reus
Type inference in TypeScript is the ability of the compiler to automatically deduce the types of variables, function return types, and expressions based on their usage and context. It reduces the need for explicit type annotations.
Ambient declarations in TypeScript are used to declare types for libraries or variables that are defined outside of the TypeScript codebase. They provide type information for external entities without requiring their actual implementation.
The 'this' keyword in TypeScript refers to the current instance of the object within which it is used. It is commonly used in class methods to access and modify object properties.
A tuple in TypeScript is an array-like data structure that allows storing a fixed number of elements of different types. Tuples enable developers to express arrays with a specific length and type for each element.
The 'never' type in TypeScript represents values that never occur. For example, a function returning 'never' might throw an error or have an infinite loop, preventing it from returning normally.
// Function returning 'never' type (never completes normally)
function throwError(message: string): never {
throw new Error(message);
}
// Variable with 'never' type (cannot have a value)
let neverVariable: never;
// Function that never returns
function infiniteLoop(): never {
while (true) {}
}
A union type in TypeScript allows a variable to have one of several specified types. It is denoted by the '|' symbol between type names. Union types provide flexibility when a variable can hold multiple types of values.
Type aliases in TypeScript allow developers to create custom names for existing types, making complex type definitions more readable and maintainable. They are especially useful for defining union types, tuple types, and complex object types.
type Point = {
x: number;
y: number;
};
let point: Point = { x: 10, y: 20 };
The 'as const' assertion in TypeScript is used to infer literal types for object properties when assigning them. It tells the compiler to treat the assigned values as readonly, narrowing their type to their literal value.
An enum in TypeScript is a way to define a set of named constants, typically representing a set of related values. Enums improve code readability and maintainability by providing meaningful names for numeric or string values.
Optional properties in TypeScript interfaces are denoted by appending a '?' after the property name. This allows objects to omit certain properties while still conforming to the interface structure.
A 'readonly' array in TypeScript is an array whose contents cannot be modified after initialization. It provides a level of immutability for arrays, preventing accidental modifications to array elements.
The 'never' type in TypeScript is typically used to denote functions that never return or variables that cannot have a value. It is often employed in scenarios where a function throws an error or enters an infinite loop.
// Function that never returns
function throwError(message: string): never {
throw new Error(message);
}
// Variable with 'never' type (cannot have a value)
let neverVariable: never;
Function types in TypeScript can be defined using arrow function syntax or traditional function syntax, along with parameter types and return type annotations. They allow specifying the signature of functions passed as arguments or assigned to variables.
he 'Partial' type in TypeScript is a utility type that constructs a type with all properties of the original type set to optional. It is commonly used to create partial versions of object types, allowing for flexible property assignment.
The 'Omit' type in TypeScript is a utility type that creates a new type by omitting specified keys from an existing type. It is useful for creating new types that exclude certain properties from the original type.
Intersection types in TypeScript are created by combining multiple types using the '&' symbol. They represent a type that has all the properties of each constituent type, allowing for the combination of different types into one.
type Animal = { name: string };
type Bird = { fly: () => void };
type FlyingAnimal = Animal & Bird;
let myPet: FlyingAnimal = { name: "Parrot", fly: () => console.log("Flying!") };
Type predicates in TypeScript are functions that return a boolean value and assert the type of a variable within a certain code block. They are commonly used in type guards to narrow down the type of a variable.
The 'Pick' type in TypeScript is a utility type that creates a new type by picking specific properties from an existing type. It allows developers to select only the desired properties from a larger type, creating a more focused type definition.
Objects in TypeScript can be created using object literal syntax, constructor functions, class constructors, or object spread syntax. Each method offers different capabilities and usage patterns depending on the scenario.
A type assertion with the 'as' keyword in TypeScript is used to tell the compiler about the type of a variable when its type is not known. It is typically written as '<Type>variable' or 'variable as Type', where 'Type' is the desired type.
let someValue: any = "this is a string";
// Type assertion using 'as' keyword
let strLength: number = (someValue as string).length;
The 'Record' type in TypeScript is a utility type that creates an object type with specified keys and value types. It is commonly used to define dictionaries or maps where the keys and value types are known in advance.
The 'never' type in TypeScript is used to represent values that never occur. It is often used to denote functions that never return or variables that cannot have a value, helping improve type safety and code clarity.
Union types in TypeScript are created by using the '|' symbol between type names. They allow a variable to have one of several specified types, providing flexibility and expressiveness in type definitions.
// Union type
let myVariable: string | number;
myVariable = "Hello"; // Valid assignment
myVariable = 123; // Valid assignment
// Type error: Cannot assign boolean to string | number
// myVariable = true;
The 'keyof' operator in TypeScript returns a union of string literal types representing the keys of an object type. For example, 'keyof { foo: number, bar: string }' would result in the type '"foo" | "bar"'.
Mapped types in TypeScript are used to transform the properties of one type into another type. They allow developers to create new types based on existing types by applying transformations to each property.
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
interface Person {
name: string;
age: number;
}
let readonlyPerson: Readonly<Person> = { name: "John", age: 30 };
// Type error: Cannot assign to 'name' because it is a read-only property
// readonlyPerson.name = "Jane";
When the type of a variable is unknown in TypeScript, a type assertion can be performed using the 'unknown' type followed by a type assertion operator like 'as'. For example, 'const value: unknown = getValue(); (value as string).toUpperCase();'
The 'readonly' modifier in TypeScript is used to indicate that a property or variable can only be assigned a value once, either in the declaration or in a constructor. It ensures immutability for object properties and array elements.
The 'Nullable' type in TypeScript is a utility type that creates a union type of the original type and 'null' or 'undefined'. It allows variables to hold either the specified type or 'null'/'undefined', providing flexibility in handling nullable values.
type Nullable<T> = T | null | undefined;
let nullableString: Nullable<string> = "Hello";
let nullableNumber: Nullable<number> = null;
let nullableBoolean: Nullable<boolean> = undefined;