Skip to main content
Cover image for TypeScript Conditional Types
Back to Work Blog
Work

TypeScript Conditional Types

Explore TypeScript Conditional Types - a powerful way to define types based on type relationships.

#typescript #conditional-types #programming

Hello! Conditional type in typescript are a way to define a type based on if the type in question is “extending” the other described type. This can be useful in many scenarios regarding input fields or output fields, depending on what you pass in. The syntax is quite similar to JavaScript’s ternary expressions, as you can see below;

interface Entity {
  health: number;
}

interface Enemy extends Entity {
  attack: () => number;
}

interface Hero {
  isHero: boolean;
}

// This would return type Enemy!
type EnemyType = Enemy extends Entity ? Enemy : Entity;

// This would return type Entity!
type NonHeroType = Enemy extends Hero ? Hero : Entity;

As you can see, if the type is extending as you expected, you get the value right after the ? , otherwise it will give back the Entity type described above. This is a primitive example just to showcase how the method works, you probably would not require something like this. Typically, you want to use Generics with Conditional Types in order to get the maximum effect.

type Primitive = string | number | boolean;

function identity<T extends Primitive | Primitive[]>(
  value: T
): T extends Primitive[] ? T[number] : T {
  return (Array.isArray(value) ? value[0] : value) as any;
}

const x = identity('hi'); // string
const y = identity([1, 2, 3]); // number

As you can see with above, the function of identity is checking whether the primitive is an array value or not, and you are able to get the type values back for whatever is inside of the array. That way you can always write a more generic function to get back the type of identity without having to sacrifice the type differences between arrays.