Generics in TypeScript provide a way to create reusable components that can work with a variety of data types while maintaining type safety. They allow you to define functions, classes, and interfaces that can operate on different types without sacrificing the benefits of TypeScript's static type checking.
Key Concepts
- Generic Functions: Functions that can accept parameters of any type, specified at the time of function invocation.
- Generic Classes: Classes that can operate on different data types, specified when the class is instantiated.
- Generic Interfaces: Interfaces that define a contract for types that can be specified later.
- Type Parameters: Placeholders for the actual types that will be used when the generic is instantiated.
Generic Functions
Generic functions allow you to create functions that can work with any data type. Here's a simple example:
function identity<T>(arg: T): T { return arg; } let output1 = identity<string>("Hello, TypeScript!"); let output2 = identity<number>(42);
Explanation
T
is a type parameter, a placeholder for the actual type that will be used.identity
is a generic function that takes an argument of typeT
and returns a value of the same type.- When calling
identity
, you specify the type you want to use, such asstring
ornumber
.
Generic Classes
Generic classes allow you to create classes that can work with any data type. Here's an example:
class Box<T> { contents: T; constructor(value: T) { this.contents = value; } } let stringBox = new Box<string>("Hello"); let numberBox = new Box<number>(123);
Explanation
Box<T>
is a generic class with a type parameterT
.contents
is a property of typeT
.- The constructor initializes
contents
with a value of typeT
. - You can create instances of
Box
with different types, such asstring
ornumber
.
Generic Interfaces
Generic interfaces define a contract for types that can be specified later. Here's an example:
interface Pair<T, U> { first: T; second: U; } let pair: Pair<string, number> = { first: "Hello", second: 42 };
Explanation
Pair<T, U>
is a generic interface with two type parameters,T
andU
.first
andsecond
are properties of typesT
andU
, respectively.- You can create objects that conform to the
Pair
interface with different types forfirst
andsecond
.
Practical Exercise
Task
Create a generic function merge
that takes two objects and merges them into one. The function should return a new object that contains all properties from both input objects.
Solution
function merge<T, U>(obj1: T, obj2: U): T & U { return { ...obj1, ...obj2 }; } const person = { name: "Alice" }; const details = { age: 30, job: "Engineer" }; const merged = merge(person, details); console.log(merged); // Output: { name: "Alice", age: 30, job: "Engineer" }
Explanation
merge
is a generic function with two type parameters,T
andU
.- It takes two objects,
obj1
andobj2
, and returns a new object that combines properties from both. - The return type
T & U
is an intersection type, representing an object that has all properties from bothT
andU
.
Common Mistakes and Tips
- Forgetting to Specify Type Parameters: Always specify the type parameters when using generics to ensure type safety.
- Overusing Generics: Use generics when necessary, but avoid overcomplicating your code with unnecessary type parameters.
- Type Inference: TypeScript can often infer the type parameters, so you may not need to specify them explicitly.
Conclusion
Generics in TypeScript provide powerful tools for creating flexible and reusable code components. By understanding and utilizing generic functions, classes, and interfaces, you can write code that is both type-safe and adaptable to various data types. In the next section, we will explore advanced TypeScript types, building on the foundation of generics to create even more robust applications.
Playwright with TypeScript: From Beginner to Advanced
Module 1: Introduction to Playwright and TypeScript
- What is Playwright?
- Setting Up Your Development Environment
- Introduction to TypeScript
- Basic TypeScript Syntax
Module 2: Getting Started with Playwright
- Installing Playwright
- Creating Your First Playwright Script
- Understanding Playwright's Core Concepts
- Running Playwright Tests
Module 3: Playwright and TypeScript Basics
- Writing Tests in TypeScript
- Using TypeScript Interfaces and Types
- Debugging Playwright Tests
- Handling Asynchronous Code
Module 4: Advanced Playwright Features
- Working with Selectors
- Handling Multiple Pages and Frames
- Network Interception and Mocking
- Emulating Devices and Geolocation
Module 5: Test Automation Strategies
- Organizing Tests and Test Suites
- Using Fixtures and Hooks
- Parallel Test Execution
- Continuous Integration with Playwright
Module 6: Advanced TypeScript Techniques
- Generics in TypeScript
- Advanced TypeScript Types
- TypeScript Decorators
- TypeScript and Playwright Best Practices
Module 7: Real-World Playwright Applications
- End-to-End Testing with Playwright
- Visual Testing with Playwright
- Performance Testing with Playwright
- Case Study: Implementing Playwright in a Project