{"id":31202858,"url":"https://github.com/itsgitz/typescript-generics","last_synced_at":"2025-09-20T14:13:13.179Z","repository":{"id":314175756,"uuid":"1054476589","full_name":"itsgitz/typescript-generics","owner":"itsgitz","description":"Learn how to use generic type in TypeScript","archived":false,"fork":false,"pushed_at":"2025-09-10T23:40:13.000Z","size":14,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-11T02:29:51.661Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/itsgitz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-10T22:37:50.000Z","updated_at":"2025-09-10T23:40:16.000Z","dependencies_parsed_at":"2025-09-11T02:29:55.044Z","dependency_job_id":"aba6dc3d-5ab1-4d8e-927c-d807790626d3","html_url":"https://github.com/itsgitz/typescript-generics","commit_stats":null,"previous_names":["itsgitz/typescript-generics"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/itsgitz/typescript-generics","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itsgitz%2Ftypescript-generics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itsgitz%2Ftypescript-generics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itsgitz%2Ftypescript-generics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itsgitz%2Ftypescript-generics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itsgitz","download_url":"https://codeload.github.com/itsgitz/typescript-generics/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itsgitz%2Ftypescript-generics/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276106042,"owners_count":25586191,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-20T02:00:10.207Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-09-20T14:13:12.316Z","updated_at":"2025-09-20T14:13:13.167Z","avatar_url":"https://github.com/itsgitz.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TypeScript Generics\n\nThis repository provides simple examples to demonstrate the use of generic types in TypeScript.\n\n## What are Generics?\n\nGenerics 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.\n\n## Example 1: Generic Type\n\nA 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.\n\nIn `src/api-response.ts`, we define a generic `ApiResponse\u003cT\u003e` type:\n\n```typescript\ntype ApiResponse\u003cT\u003e = {\n  data: T;\n  success: boolean;\n  error?: string;\n};\n```\n\nThe `T` is a placeholder for a type that will be provided when we use `ApiResponse`.\n\n### Usage\n\nWe can then use this generic type for different kinds of data.\n\n#### Response with a User object\n\n```typescript\ntype User = { id: string; name: string };\n\nconst userResponse: ApiResponse\u003cUser\u003e = {\n  data: {\n    id: \"1\",\n    name: \"Putri\",\n  },\n  success: true,\n};\n```\n\nHere, `T` is replaced with `User`.\n\n#### Response with a string\n\n```typescript\nconst stringResponse: ApiResponse\u003cstring\u003e = {\n  data: \"Hello world!\",\n  success: true,\n};\n```\n\nHere, `T` is replaced with `string`.\n\n## Example 2: Generic Function\n\nGenerics 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.\n\nIn `src/api-client.ts`, we define a generic `fetchJSON\u003cT\u003e` function to fetch and parse data from a URL:\n\n```typescript\nasync function fetchJSON\u003cT\u003e(url: string): Promise\u003cT\u003e {\n  const res = await axios.get(url);\n  if (!res.status.toString().startsWith(\"2\")) {\n    throw new Error(res.statusText);\n  }\n  return res.data;\n}\n```\n\nHere, `T` represents the expected type of the data in the response body. The function promises to return a value of that type.\n\n### Usage\n\nWe can use this function to fetch different types of data by specifying the type when we call it.\n\n```typescript\ntype Todo = {\n  userId: number;\n  id: number;\n  title: string;\n  completed: boolean;\n};\n\n// We expect an array of Todo objects\nconst todos = await fetchJSON\u003cTodo[]\u003e(\n  \"https://jsonplaceholder.typicode.com/todos\"\n);\n```\n\nIn 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.\n\n## Example 3: Generic Class with Constraints\n\nWe 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.\n\nIn `src/base-repository.ts`, we define a generic `InMemoryRepository\u003cT\u003e` that can work with any entity type, as long as that entity has an `id` property.\n\nFirst, we define a generic `Repository` interface:\n\n```typescript\ninterface Repository\u003cT\u003e {\n  findById(id: string): Promise\u003cT | null\u003e;\n  findAll(): Promise\u003cT[]\u003e;\n  create(item: T): Promise\u003cT\u003e;\n  update(id: string, item: Partial\u003cT\u003e): Promise\u003cT\u003e;\n  delete(id: string): Promise\u003cboolean\u003e;\n}\n```\n\nThen, we implement this with a generic class that uses a constraint.\n\n```typescript\nclass InMemoryRepository\u003cT extends { id: string }\u003e implements Repository\u003cT\u003e {\n  private store: Map\u003cstring, T\u003e = new Map();\n\n  // ... implementation ...\n\n  async create(item: T): Promise\u003cT\u003e {\n    // We can safely access item.id because of the constraint\n    this.store.set(item.id, item);\n    return item;\n  }\n\n  // ... other methods\n}\n```\n\nThe key part is `\u003cT extends { id:string }\u003e`. 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.\n\n### Usage\n\nWe can now create repositories for different entities that match the constraint.\n\n```typescript\n// Entities that satisfy the constraint { id: string }\ntype User = {\n  id: string;\n  name: string;\n};\n\ntype Product = {\n  id: string;\n  name: string;\n  price: number;\n};\n\nconst userRepository = new InMemoryRepository\u003cUser\u003e();\nconst productRepository = new InMemoryRepository\u003cProduct\u003e();\n```\n\n## How to Run\n\n1.  Install dependencies:\n    ```bash\n    bun install\n    ```\n2.  Run the examples:\n    ```bash\n    # Run the generic type example\n    bun src/api-response.ts\n\n    # Run the generic function example\n    bun src/api-client.ts\n\n    # Run the generic class example\n    bun src/base-repository.ts\n    ```\n\nThis will execute the `main` functions in each file and log the results to the console.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitsgitz%2Ftypescript-generics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitsgitz%2Ftypescript-generics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitsgitz%2Ftypescript-generics/lists"}