Typescript Features
Sraban Pahadasingh June 25, 2024 01:13 AMTypeScript concepts:
01. Type Assertion
Type assertion in TypeScript is a way to tell the compiler that you know more about the type of a value than TypeScript can infer automatically. It has two forms:
-
Angle-bracket syntax:
<Type>value
let myList = [1, 2, 3]; let length1 = (<number[]>myList).length; // Using angle-bracket syntax
-
As syntax:
value as Type
let length2 = (myList as number[]).length; // Using 'as' syntax
Type assertion does not change the runtime behavior but helps TypeScript's type checker understand the intended type when the developer has more specific knowledge about it.
02. TypeScript Generics
Generics in TypeScript allow you to create reusable components that can work with a variety of data types while maintaining type safety. The syntax for generics involves using angle brackets (< >
) to declare type parameters:
function myMethod<T>(arg: T): T {
return arg;
}
let value = myMethod<number>(10); // Specify the type explicitly
let anotherValue = myMethod("Hello"); // TypeScript infers the type
Generics can be used with interfaces, classes, functions, properties, and variables to create flexible and type-safe constructs.
03. typeof
and keyof
typeof
: Returns the type of a variable, function, or object.
let x = 10;
type T = typeof x; // T is 'number'
keyof
: Returns the union of keys of a given type.
interface Person {
name: string;
age: number;
}
type Keys = keyof Person; // Keys is 'name' | 'age'
04. Type Inference
Type inference in TypeScript refers to the ability of the type system to deduce types in certain situations based on the context and initialization values, without requiring explicit type annotations:
let x = 10; // TypeScript infers 'number' type for x
let y = "Hello"; // TypeScript infers 'string' type for y
Type inference reduces the need for manual type annotations, making code more concise while maintaining type safety.
05. Type Aliases
Type aliases in TypeScript allow you to create new names for existing types. They are particularly useful for defining complex types or for simplifying type annotations:
type Container<T> = { value: T };
let numContainer: Container<number> = { value: 10 };
let strContainer: Container<string> = { value: "Hello" };
Type aliases improve code readability and maintainability by providing descriptive names for types.
06. Conditional Types
Conditional types in TypeScript enable the creation of types that depend on the relationships between types:
type TypeName<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
"unknown";
let strType: TypeName<string> = "string";
let numType: TypeName<number> = "number";
Conditional types use the extends
keyword to check if a type satisfies a condition and then return different types based on that condition (X
if true, Y
if false).
07. Distributive Conditional Types
Distributive conditional types in TypeScript automatically distribute over union types:
type BoxedValue<T> = { value: T };
type BoxedNumber = BoxedValue<number | string>;
// Equivalent to:
// type BoxedNumber = BoxedValue<number> | BoxedValue<string>;
When a conditional type is applied to a union type, TypeScript applies the type condition to each constituent type of the union.
08. Object-Oriented Principles supported by TypeScript
TypeScript supports fundamental object-oriented principles such as:
-
Encapsulation: Bundling data and methods that operate on the data into a single unit (class).
-
Inheritance: Creating new classes (derived classes) from existing ones (base classes) to reuse and extend functionality.
- Polymorphism: Using a single interface to represent multiple types (subtyping), allowing objects of different types to be treated as instances of a common superclass.
09. Awaited Type and Promise Improvements
TypeScript 4.3 introduced the Awaited
type to extract the type awaited by a Promise:
type Awaited<T> = T extends PromiseLike<infer U> ? U : T;
async function fetchData(): Promise<string> {
return "Data";
}
type Data = Awaited<ReturnType<typeof fetchData>>; // Data is 'string'
This improvement enhances type inference and provides better support for async functions and promise chains.
10. Recursive Type Aliases
Recursive type aliases in TypeScript allow defining types that reference themselves:
type TreeNode<T> = {
value: T;
left?: TreeNode<T>;
right?: TreeNode<T>;
};
let node: TreeNode<number> = {
value: 10,
left: {
value: 5
}
};
Recursive type aliases are useful for defining recursive data structures like trees or linked lists.