Generics <T>【TypeScript】
Tags: webdev, typescript
Published: 2024-07-01 22:44:29

The idea of Generics makes us confused, especially beginners. I am also one of such persons. Hence, I researched how to use generics in TypeScript.

## What is Generics? 
TypeScript generics are a feature that allows types to be treated as parameters, enhancing reusability and type safety. By using generics, you can write code that does not depend on specific types. But I guess some people still don't get it. So I will share the some examples with you.

## How to use it

```typescript
interface Interface1 {
  value1: string;
  value2: string;
}

interface Interface2 {
  value1: number;
  value2: number;
}

const test1: Interface1 = {
  value1: "John",
  value2: "ABC",
};

const test2: Interface2 = {
  value1: 123,
  value2: 456,
};
```
We have two objects, Test1 and Test2. The key names for Test1 and Test2 are the same, but the types are different, with one being string and the other being number. In this case, we need to create interfaces for each respective type. However, this requires creating a separate interface for each type, which Generics solves for us."

```typescript
interface Interface3<T> {
  value1: T;
  value2: T;
}

const test3: Interface3<number> = {
  value1: 123,
  value2: 456,
};
const test4: Interface3<string> = {
  value1: "John",
  value2: "ABC",
};
```
When defining types, using &lt;T&gt; allows us to reuse a single interface by specifying the type as an argument when declaring variables. This makes it easier to create reusable interfaces, even when new types of objects are added. By the way, &lt;T&gt; can be replaced with '&lt;A&gt;, &lt;B&gt; or any other preferred name. &lt;T&gt; is commonly used in general

## extends
Generics allow you to impose constraints on types. When you want to specify that <T> must be  specific types, you use extends for this purpose.

```typescript
interface Interface4<T extends string | number> {
  value1: T;
  value2: T;
}

const test1: Interface4<string> = {
    value1: "John",
    value2: "ABC",
  };
  
  const test2: Interface4<number> = {
    value1: 123,
    value2: 456,
  };
  
const test3: Interface4<boolean> = {
  value1: true,
  value2: false,
};//error happened
```
In this case, by using extends with string and number, we specify that T cannot accept any other types. Therefore, test3 caused an error because it was assigned a type of boolean.


## Generics in function.
Generics can be used in function. Even when you don't want to specify the types of arguments or return values to a specific type when declaring a function, you can use &lt;T&gt;. You write &lt;T&gt; between the function name and the arguments to denote the use of generics. The declaration would look like the following:

```typescript
function func1<T>(value: T): T {
  return value;
}
//same function
const func2 = <T>(value: T): T => {
  return value;
};

func1<string>("John");
func2<number>(100);
func2<boolean>(true);
```
By passing a type as an argument when calling a function, you can determine the type for that function.Of course, using extends allows you to impose type constraints as well.

```typescript
function func1<T extends string | boolean>(value: T): T {
  return value;
}
func1<string>("John");
func1<number>(100); //error happened
func1<boolean>(true);
```