How to constrain or control a generic type parameter using another generic type parameter in TypeScript?
Tags: typescript
Published: 2022-01-17 00:00:00

---
  title: How to constrain or control a generic type parameter using another generic type parameter in TypeScript?
  published: true
  tags: TypeScript
  date: Mon Jan 17 2022 05:30:00 GMT+0530 (India Standard Time)
  canonical_url: https://melvingeorge.me/blog/constrain-control-generic-type-parameter-using-another-generic-type-parameter-typescript
  cover_image: https://melvingeorge.me/_next/static/images/main-629ad55ca93a1e45d61a886422587cf4.jpg
  ---
  [Originally posted here!](https://melvingeorge.me/blog/constrain-control-generic-type-parameter-using-another-generic-type-parameter-typescript)
  
In order to control or constrain a generic type parameter using another generic type parameter, we can use the `extends` keyword after the name of the generic type parameter to be controlled or constrained, followed by the name of the other generic type parameter type and the constraint to be applied.

### TL;DR

```ts
// a generic function to search for a value within an array
// also constraining the Type2 generic type paramter with whatever values type
// the Type1 generic type paramter will hold
function searchArr<Type1, Type2 extends Type1>(
  arr: Type1[],
  valueToSearch: Type2
) {
  return arr.indexOf(valueToSearch); // Valid ✅.
}

/* call the function with different array values type */

// ✅ Valid function calls
searchArr(["John", "Lily", "Roy"], "Lily");
searchArr([1, 2, 3, 4], 5);

// ❌ Error since the value to search is of another
// type and not of type of the values in the array
searchArr(["John", "Lily", "Roy"], 1);
```

For example, let's say we have a function that takes `2` arguments where the first argument is an array and the second argument is a value to search within the array. The function returns the index of the item in the array.

The logic of the function may look like this, wihtout any types,

```ts
// function to search for a value within an array
function searchArr(arr, valueToSearch) {
  return arr.indexOf(valueToSearch);
}
```

Now let's make 2 generic type parameters called `Type1` and `Type2` within the angled brackets syntax (`<>`) and then assign those generic type parameters respectively as the types for the `arr` parameter and the `valueToSearch` parameter.

The `arr` parameter needs to have a type of `Type1[]` since this parameter is an array.

This is done to make our `searchArr` function into a reusable generic function.

it can be done like this,

```ts
// a generic function to search for a value within an array
function searchArr<Type1, Type2>(arr: Type1[], valueToSearch: Type2) {
  // Error ❌. Argument of type 'Type2' is not assignable to parameter of type 'Type1'.
  return arr.indexOf(valueToSearch);
}
```

The above code looks fine but the TypeScript compiler will start showing an error saying that the `Argument of type 'Type2' is not assignable to parameter of type 'Type1'.`.

This is because since we are using different `generic type parameters` for both `arr` and the `valueToSearch` parameters (namely `Type1` and `Type2`), the TypeScript compiler doesn't know beforehand which type to use and the types for these 2 parameters can be different whenever this function is called or invoked.

This is where the concept of constraining one of the generic type parameters to the other comes into play.

In our case since the first parameter `arr` can accept an array of any type then we should limit the `valueToSearch` parameter type to be of the same type as the values in the array.

To achive this functionality let's use the `extends` keyowrd after the `Type2` generic type parameter adn then associate the `Type1` generic type parameter like this,

```ts
// a generic function to search for a value within an array
// also constraining the Type2 generic type paramter with whatever values type
// the Type1 generic type paramter will hold
function searchArr<Type1, Type2 extends Type1>(
  arr: Type1[],
  valueToSearch: Type2
) {
  return arr.indexOf(valueToSearch); // Valid ✅.
}
```

Now, as soon as we constraint the `Type2` with `Type1` generic parameter type the error is gone and the TypeScript compiler is happy with it.

Now let's call the `searchArr` function with differnet kind of array values type liek this,

```ts
// a generic function to search for a value within an array
// also constraining the Type2 generic type paramter with whatever values type
// the Type1 generic type paramter will hold
function searchArr<Type1, Type2 extends Type1>(
  arr: Type1[],
  valueToSearch: Type2
) {
  return arr.indexOf(valueToSearch); // Valid ✅.
}

/* call the function with different array values type */

// ✅ Valid function calls
searchArr(["John", "Lily", "Roy"], "Lily");
searchArr([1, 2, 3, 4], 5);

// ❌ Error since the value to search is of another
// type and not of type of the values in the array
searchArr(["John", "Lily", "Roy"], 1);
```

As you can see from the above code the first 2 function calls are valid as it satisfies generic type parameter constraints and the last call is an error.

We have successfully constrained the generic type parameter with another generic type parameter. Yay 🥳!

See the above code live in [codesandbox](https://codesandbox.io/s/constrain-control-generic-type-parameter-using-another-generic-type-parameter-typescript-xi4t0?file=/src/index.ts).

That's all 😃!

### Feel free to share if you found this useful 😃.

---