How to dynamically get the interface or type alias property value types from conditional types in TypeScript?
Tags: typescript
Published: 2022-01-29 00:00:00

---
  title: How to dynamically get the interface or type alias property value types from conditional types in TypeScript?
  published: true
  tags: TypeScript
  date: Sat Jan 29 2022 05:30:00 GMT+0530 (India Standard Time)
  canonical_url: https://melvingeorge.me/blog/dynamically-get-interface-or-type-alias-property-value-type-from-conditional-types-typescript
  cover_image: https://melvingeorge.me/_next/static/images/main-24fe95a8225198ca159c351976dc3adb.jpg
  ---
  [Originally posted here!](https://melvingeorge.me/blog/dynamically-get-interface-or-type-alias-property-value-type-from-conditional-types-typescript)
  
To dynamically get an interface or type alias property value type from [conditional types](https://melvingeorge.me/blog/choose-types-conditionally-from-another-type-typescript), you can use the `infer` keyword followed by declaring a `generic type name` wherever you need to get the value from and then using that value as the truthy value in the conditional type check in TypeScript.

### TL;DR

```ts
// a generic conditional type
type GetSalaryType<T> = T extends { salary: infer value } ? value : never;

// an interface where the salary
// property is `string` type
interface Person {
  name: string;
  salary: string;
}

// an interface where the salary
// property is `number` type
interface Person2 {
  name: string;
  salary: number;
}

// an interface where the salary
// property is an `array of string` type
interface Person3 {
  name: string;
  salary: string[];
}

// get the type of the `salary` property
// from the all the above interfaces
type SalaryType = GetSalaryType<Person>; // string
type SalaryType2 = GetSalaryType<Person2>; // number
type SalaryType3 = GetSalaryType<Person3>; // string[]
```

For example, first, let's consider a small scenario where we need to choose between the type `string` and the `number` type by checking if the `interface` or the `type alias` contains a property called `salary`.

So in this case the better way is to use a `conditional type` and make the whole type into a `generic type alias`.

It can be done like this,

```ts
// a generic conditional type
type GetSalaryType<T> = T extends { salary: string } ? string : never;
```

Now let's create an interface called `Person` with properties called `name` and `salary` having the type of `string`.

It can be done like this,

```ts
// a generic conditional type
type GetSalaryType<T> = T extends { salary: string } ? string : never;

// a simple interface called Person
interface Person {
  name: string;
  salary: string;
}
```

Now let's pass the `Person` interface to the `GetSalaryType` generic conditional type like this,

```ts
// a generic conditional type
type GetSalaryType<T> = T extends { salary: string } ? string : never;

// a simple interface called Person
interface Person {
  name: string;
  salary: string;
}

// get the type of the `salary` property
// from the `Person` interface
type SalaryType = GetSalaryType<Person>; // string
```

Now if you hover over the `SalaryType` type you can see that the type is of `string` that is correct and satisfies our needs in this case.

But we know that `salary` can have many forms like `string`, `number` or even an `array` of salaries. If we pass a type where the `salary` type is `number` to the `GetSalaryType` then also we will get the type of `string` in the `SalaryType` type alias which may not suit our needs.

So to make the `GetSalaryType` conditional generic type into a more flexible type let's use the `infer` keyword after the `salary` property in the condition followed by a generic type name. Let's name the generic type name as `value` and then use that as the truthy value in the condition.

It can be done like this,

```ts
// a generic conditional type
type GetSalaryType<T> = T extends { salary: infer value } ? value : never;

// a simple interface called Person
interface Person {
  name: string;
  salary: string;
}

// get the type of the `salary` property
// from the `Person` interface
type SalaryType = GetSalaryType<Person>; // string
```

Now let's make 2 more interfaces called `Person2` and `Person3` where the `salary` property is of `number` type and an `array of strings` type respectively and then pass that to the `GetSalaryType` conditional generic type.

It can be done like this,

```ts
// a generic conditional type
type GetSalaryType<T> = T extends { salary: infer value } ? value : never;

// an interface where the salary
// property is `string` type
interface Person {
  name: string;
  salary: string;
}

// an interface where the salary
// property is `number` type
interface Person2 {
  name: string;
  salary: number;
}

// an interface where the salary
// property is an `array of string` type
interface Person3 {
  name: string;
  salary: string[];
}

// get the type of the `salary` property
// from the all the above interfaces
type SalaryType = GetSalaryType<Person>; // string
type SalaryType2 = GetSalaryType<Person2>; // number
type SalaryType3 = GetSalaryType<Person3>; // string[]
```

As you can see that the `SalaryType`, `SalaryType2`, and the `SalaryType3` have different types according to the interfaces passed to the `GetSalaryType` conditional generic type.

We have dynamically got the `interface` property value type from conditional types successfully in TypeScript. Yay 🥳!

See the above code live in [codesandbox](https://codesandbox.io/s/dynamically-get-interface-or-type-alias-property-value-type-from-conditional-types-typescript-y50bc4?file=/src/index.ts).

That's all 😃!

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

---