https://github.com/itsgitz/typescript-generics
Learn how to use generic type in TypeScript
https://github.com/itsgitz/typescript-generics
Last synced: 10 months ago
JSON representation
Learn how to use generic type in TypeScript
- Host: GitHub
- URL: https://github.com/itsgitz/typescript-generics
- Owner: itsgitz
- License: mit
- Created: 2025-09-10T22:37:50.000Z (11 months ago)
- Default Branch: master
- Last Pushed: 2025-09-10T23:40:13.000Z (11 months ago)
- Last Synced: 2025-09-11T02:29:51.661Z (11 months ago)
- Language: TypeScript
- Size: 13.7 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# TypeScript Generics
This repository provides simple examples to demonstrate the use of generic types in TypeScript.
## What are Generics?
Generics allow you to create reusable components that can work with a variety of types rather than a single one. This enhances flexibility and type safety.
## Example 1: Generic Type
A common use case for generics is to create a wrapper for API responses. The structure of the response is often the same (e.g., it has a `data` field, a `success` flag, and an optional `error` message), but the type of the `data` can vary.
In `src/api-response.ts`, we define a generic `ApiResponse` type:
```typescript
type ApiResponse = {
data: T;
success: boolean;
error?: string;
};
```
The `T` is a placeholder for a type that will be provided when we use `ApiResponse`.
### Usage
We can then use this generic type for different kinds of data.
#### Response with a User object
```typescript
type User = { id: string; name: string };
const userResponse: ApiResponse = {
data: {
id: "1",
name: "Putri",
},
success: true,
};
```
Here, `T` is replaced with `User`.
#### Response with a string
```typescript
const stringResponse: ApiResponse = {
data: "Hello world!",
success: true,
};
```
Here, `T` is replaced with `string`.
## Example 2: Generic Function
Generics are also incredibly useful for functions. You can create a function that operates on or returns a value whose type is not known ahead of time.
In `src/api-client.ts`, we define a generic `fetchJSON` function to fetch and parse data from a URL:
```typescript
async function fetchJSON(url: string): Promise {
const res = await axios.get(url);
if (!res.status.toString().startsWith("2")) {
throw new Error(res.statusText);
}
return res.data;
}
```
Here, `T` represents the expected type of the data in the response body. The function promises to return a value of that type.
### Usage
We can use this function to fetch different types of data by specifying the type when we call it.
```typescript
type Todo = {
userId: number;
id: number;
title: string;
completed: boolean;
};
// We expect an array of Todo objects
const todos = await fetchJSON(
"https://jsonplaceholder.typicode.com/todos"
);
```
In this case, we tell `fetchJSON` that `T` should be `Todo[]`, and TypeScript will ensure that the `todos` constant is correctly typed as an array of `Todo` objects.
## Example 3: Generic Class with Constraints
We can also create generic classes. A powerful feature to use with generic classes (and functions) is **constraints**. Constraints allow us to limit the kinds of types that can be used as a type argument.
In `src/base-repository.ts`, we define a generic `InMemoryRepository` that can work with any entity type, as long as that entity has an `id` property.
First, we define a generic `Repository` interface:
```typescript
interface Repository {
findById(id: string): Promise;
findAll(): Promise;
create(item: T): Promise;
update(id: string, item: Partial): Promise;
delete(id: string): Promise;
}
```
Then, we implement this with a generic class that uses a constraint.
```typescript
class InMemoryRepository implements Repository {
private store: Map = new Map();
// ... implementation ...
async create(item: T): Promise {
// We can safely access item.id because of the constraint
this.store.set(item.id, item);
return item;
}
// ... other methods
}
```
The key part is ``. This tells TypeScript that `T` can be any type, as long as it has a property `id` of type `string`. This allows us to safely use `item.id` inside our class methods.
### Usage
We can now create repositories for different entities that match the constraint.
```typescript
// Entities that satisfy the constraint { id: string }
type User = {
id: string;
name: string;
};
type Product = {
id: string;
name: string;
price: number;
};
const userRepository = new InMemoryRepository();
const productRepository = new InMemoryRepository();
```
## How to Run
1. Install dependencies:
```bash
bun install
```
2. Run the examples:
```bash
# Run the generic type example
bun src/api-response.ts
# Run the generic function example
bun src/api-client.ts
# Run the generic class example
bun src/base-repository.ts
```
This will execute the `main` functions in each file and log the results to the console.